어셈블리 프로그램의 세 가지 섹션에 대해 배웠다. 이 섹션들은 다양한 메모리 세그먼트들을 표현한다.
흥미롭게도, section
키워드를 segment
로 바꾸어도 동일한 결과를 얻을 수 있다.
❗️ 64비트 Intel macOS에서 동작하는 코드이다.
segment .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 시스템 콜을 호출한다.
segment .data
msg db 'Hello, World!', 0xa ; 출력할 문자열
len equ $ - msg ; 문자열의 길이
구분된 메모리 모델은 시스템 메모리를 독립된 세그먼트 그룹으로 나눈다. 이 독립된 세그먼트들은 세그먼트 레지스터에 위치한 포인터로 참조한다. 각 세그먼트는 데이터의 특정 타입을 저장하는데 사용된다. 먼저 code 세그먼트는 명령어를 담고, data 세그먼트는 데이터들을 저장한다. 마지막으로 stack은 프로그램 스택을 관리한다.
Data 세그먼트 : .data
섹션과 .bss
섹션으로 표현된다. .data
섹션은 프로그램에 사용되는 데이터가 저장되는 메모리 지역을 선언하는데 사용된다. 이 섹션은 데이터가 선언된 후에는 변경될 수 없다. 그리고 프로그램이 실행되는 동안 정적으로 존재한다. .bss
섹션 또한 정적 메모리 섹션이다. 하지만 .bss
섹션은 프로그램에서 나중에 값이 초기화 되거나 변경될 수 있다. .bss
섹션의 메모리는 0으로 채워진다.
Code 세그먼트 : .text
섹션으로 표현된다. 명령어 코드들을 저장하는 메모리 영역을 정의한다. 이 영역은 고정된 영역이다.
Stack : 프로그램에서 함수에 전달되는 데이터 값을 저장하는 영역