macOS 에서 링킹 시 crt1.o 를 같이 import 해야 한다
crt1.o 에는 macOS loader 에서 실행하는 start() 함수가 구현되어 있다
https://opensource.apple.com/source/Csu/Csu-85/
start.s 를 보면 start 함수가 arhictecture 에 따라 구현되어 있는 것을 확인 할 수 있다.
#if __x86_64__ start: pushq $0 # push a zero for debugger end of frames marker movq %rsp,%rbp # pointer to base of kernel frame andq $-16,%rsp # force SSE alignment movq 8(%rbp),%rdi # put argc in %rdi leaq 16(%rbp),%rsi # addr of arg[0], argv, into %rsi movl %edi,%edx # copy argc into %rdx addl $1,%edx # argc + 1 for zero word sall $3,%edx # * sizeof(char *) addq %rsi,%rdx # addr of env[0], envp, into %rdx #if OLD_LIBSYSTEM_SUPPORT call __start # call _start(argc, argv, envp) hlt # should never return #else movq %rdx,%rcx jmp Lapple2 Lapple: add $8,%rcx Lapple2:cmpq $0,(%rcx) # look for NULL ending env[] array jne Lapple add $8,%rcx # once found, next pointer is "apple" parameter now in %rcx call _main movl %eax,%edi # pass result from main() to exit() call _exit # need to use call to keep stack aligned hlt #endif #endif // __x86_64__
call _main 부분에서 우리가 흔히 만드는 main 함수를 call 하는 부분이 되며
call _exit 를 통해 프로세스를 종료한다
main 함수에서 exit 를 호출하면 call _exit 전에 프로세스가 종료된다
<stdlib.h> 에 있는 exit 함수와 start.s 에서 call _exit 로 호출되는 함수는 동일하다