[libasm] Assembly - 기본구문

Park Sejin·2021년 3월 28일
0
post-thumbnail

data 섹션

data 섹션은 초기화된 데이터나 상수를 선언하는데 사용된다. 이 데이터들은 프로그램이 실행되는 동안 변경되지 않는다. data 섹션에서 상수, 파일이름, 버퍼 사이즈 등을 선언할 수 있다.

data 섹션을 선언하는 구문은 다음과 같다.

section .data

bss 섹션

bss 섹션은 초기화 되지 않는 변수를 선언하는데 사용된다.

bss 섹션을 선언하는 구문은 다음과 같다.

section .bss

text 섹션

text 섹션은 실제 코드를 작성하는데 사용된다. text 섹션은 반드시 global _start 선언과 함께 시작되어야 한다. global _start는 커널에게 프로그램이 어디에서부터 실행이 시작되는지 알려주는 역할을 한다.

text 섹션을 선언하는 구문은 다음과 같다.

section .text
  global _start
_start:

❗️   macOS에서는 _start 대신 _main으로 작성해야 한다.

어셈블리어 구문

어셈블리어 구문은 한 줄에 하나씩 입력된다.

[레이블] 명령어 [피연산자] [;주석]

대괄호 안의 필드는 선택사항이다.

어셈블리어 구문의 몇가지 예

INC COUNT         ; 메모리 변수 COUNT를 증가시킨다.
MOV TOTAL, 48     ;48을 메모리 변수 TOTAL에 저장한다.
ADD AH, BH        ; BH 레지스터의 값을 AH 레지스터의 값에 더한다.
AND MASK1, 128    ; 변수 MASK1과 128의 AND 연산을 수행한다.
ADD MARKS, 10     ; 변수 MARKS에 10을 더한다.
MOV AL, 10        ; AL 레지스터에 값 10을 저장한다.

어셈블리어로 작성한 hello world 프로그램

❗️   64비트 Intel macOS에서 동작하는 코드이다.

section .text
	global _main	        ; 링커가 알 수 있도록 반드시 선언해주어야 한다.

_main:		                ; 시작점을 링커에 알려준다.
	mov rdx, len	        ; 메세지 길이를 rdx 레지스터에 저장한다.
	mov rsi, msg	        ; 메세지를 rsi 레지스터에 저장한다.
	mov rdi, 1		; rdi 레지스터에 파일디스크립터를 1(표준출력)로 저장한다.
	mov rax, 0x2000004	; rax 레지스터에 write 시스템콜을 저장한다.
	syscall		        ; write 시스템 콜을 호출한다.

	mov rax, 0x2000001	; rax 레지스터에 exit 시스템콜을 저장한다.
	mov rdi, 0		; exit 함수의 파라미터에 0을 저장한다. 그렇지 않으면 프로그램 종료 시 exit code를 리턴한다.
	syscall	                ; exit 시스템 콜을 호출한다.

section .data
	msg db 'Hello, World!', 0xa	; 출력할 문자열
	len equ $ - msg			; 문자열의 길이

위의 코드를 컴파일하고 실행하면 다음과 같은 결과를 얻을 수 있다.

Hello, World!

NASM을 사용한 어셈블리 프로그램 컴파일, 링킹

  1. 위의 코드를 작성하고 hello.s로 저장한다.
  2. 현재 위치가 hello.s 파일이 존재하는 디렉토리인지 컴파일하기 전에 확인한다.
  3. nasm -f macho64 hello.s를 입력하여 컴파일한다.
  4. 오류가 발생하지 않았다면 hello.o라는 목적파일이 생성된다.
  5. 목적파일을 링크하고 실행파일을 생성하기 위해 ld -lSystem -o hello hello.o를 입력한다.
  6. ./hello를 입력하여 프로그램을 실행한다.

모든 절차를 올바르게 수행했다면, 스크린에 "Hello, World!"가 표시된다.

출처

tutorialspoint.com

0개의 댓글