Notice
Recent Posts
Recent Comments
Link
비트와 자장가
x86_64 어셈블리어 링킹linking 본문
728x90
아래는 시스템콜 write를 호출해 "hello world"와 개행문자를 출력하는 간단한 C 프로그램이다:
#include <unistd.h>
int main()
{
write(1, "hello world\n", 12);
}
gcc hello.c && ./a.out
위를 맥용 어셈블리어로 바꾸면 아래와 같다:
global start
section .text
start:
mov rax, 0x02000004 ;write()
mov rdi, 1
mov rsi, string
mov rdx, 12
syscall
mov rax, 0x02000001 ;exit()
xor rdi, rdi
syscall
section .data
string:
db "hello world",10 ;"hello world\n"
nasm -f macho64 hello.s && ld -static hello.o && ./a.out
위의 명령이 어떠한 경고도 뜨지 않고 제일 간단하다.
리눅스에서는 write의 주소로 0x02000004 대신 1, exit의 주소로 0x02000001 대신 60을 사용하여, 아래의 명령으로 실행 가능하다.
nasm -f elf64 hello.s && ld hello.o && ./a.out
맥OS 빅서 11.0.1 에서부터 다이나믹 라이브러리의 위치가 달라져 링킹의 방식도 달라졌다.
위의 방식 외에도 ld의 링킹 명령을 다음으로 대체 가능하다:
ld hello.o -macosx_version_min 11.0 -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem
ld hello.o -macosx_version_min 10.7
하지만 11.0 이전 버전의 링킹은 deprecated 되었으므로 사용하지 말자.
global _main
section .text
_main:
mov rax, 0x02000004
mov rdi, 1
mov rsi, string
mov rdx, 12
syscall
mov rax, 0x02000001
xor rdi, rdi
syscall
section .data
string:
db "hello world",10
_main 라벨을 사용하면 ld 대신 gcc로 바로 링킹해도 된다(gcc가 알아서 ld를 사용해주므로).
nasm -f macho64 hello.s && gcc hello.o && ./a.out
start나 _main 말고 아무 라벨을 붙이고 엔트리 포인트를 그곳으로 직접 지정하는 방법도 있다.
global hello
section .text
hello:
mov rax, 0x02000004
mov rdi, 1
mov rsi, string
mov rdx, 12
syscall
mov rax, 0x02000001
xor rdi, rdi
syscall
section .data
string:
db "hello world",10
nasm -f macho64 hello.s && ld -static -e hello hello.o && ./a.out
728x90
반응형
'개발 > 자료' 카테고리의 다른 글
직접 만들지 못하는 것은 이해하지 못하는 것 (0) | 2022.05.16 |
---|---|
엑스코드 없이 에이전트 앱 개발 (0) | 2022.04.04 |
논리회로logic gate와 비트 (0) | 2021.01.28 |
정적타입 언어를 위한 자료형data type 개론 (0) | 2020.09.29 |
프로그램 언어의 기초 (1) | 2020.09.19 |
Comments