#keywords startup,linux,assembly,crt #title Linux환경에서의 StartUpCode (Assembly) [wiki:Home 대문] / [wiki:CategoryProgramming 프로그래밍] / [wiki:LinuxStartUpCode Linux환경에서의 StartUpCode (Assembly)] ---- == [wiki:LinuxStartUpCode Linux환경에서의 StartUpCode (Assembly)] == * 작성자 조재혁([mailto:minzkn@minzkn.com]) * 고친과정 2002년 12월 23일 : 처음씀 [[TableOfContents]] == 개요 == 이 소스는 Linux에서 간략하게 구현된 startup코드입니다.[[br]] 이것은 인자를 받기 위해서 DOS처럼 공백을 구분해서 만들어야 하는 불편함이 없습니다.[[br]] Linux에서는 프로그램이 구동되면 마치 하나의 함수를 호출한것같이 스택에 해당 PSP(Linux에서도 이렇게 부르는지는 잘 모르겠네요.)를 넘겨주게 됩니다.[[br]] 때문에 DOS 보다는 상당히 편하게 사용할수 있습니다.[[br]] 그리고 아래의 예제에서 env는 인자로 넘겨주지 않았습니다.[[br]] 사실 저는 쓸일이 없어서 예제를 이따위로 만들어 놓았습니다. 너그럽게 용서하시길 바라면서 다음과 같이 예제를 올려봅니다. NOTE: Startup 코드는 Linux에서 C를 할때 링크과정에서 항상 포함되는 crt<0..1>.o 를 말합니다.[[br]] 즉, 이것이 하는 일은 프로그램이 기동되고 몇가지 기초과정(아래에서는 빠졌지만 이것보다 훨씬 많은 일을 해야 합니다.)를 초기화 하고 마지막으로 main을 호출하게 됩니다.[[br]] 그리고 main에서 return되었을때 exit(0)함수를 호출하는 것과 같은 역할의 코드를 수행해주도록 합니다. {{{#!enscript asm # # [ GPL ] # # File : mzstartup.c # Code : JaeHyuk Cho # Date : 2002.12.23 MON .code32 .globl mzstartup /* 외부(Linker)에서 Startup entry를 기본값으로 _start를 호출하게 됩니다. 하지만 이 예제에서는 mzstartup이라는 라벨을 개인적인 편의로 사용하는것으로 Linker에 의해서 Link과정을 수행할때 이 라벨을 지정해줘야 합니다. */ /* Global로 이 변수를 갖게 하여 굳이 main함수 내에서만 참조할수 있는것이 아니고 다른 함수에서도 이 전역변수를 통해서 접근할수 있게 편의상 public으로 선언합니다. */ .globl g_Argc .globl g_Argv /* 이것이 외부참조되는 C의 main함수를 가르킵니다. C++의 경우는 _main이 될수도 있고 __main도 될수 있는데 이것은 따로 알아보시기 바랍니다. (컴파일러마다 다를수 있다는 예기) */ .extern main .org 0x0000 mzstartup: /* 이 시점부터 스택에 초기화 되어 있는 상태이고 마치 mzstartup부분을 호출해준것과 같은 스택 구조를 갖게 됩니다. 그래서 일반적은 스택프레임을 다루듯 argc, argv를 복사하여 가져오게 되면 됩니다. */ pushl %ebp movl %esp, %ebp leal 0x0008(%ebp), %eax movl %eax, g_Argv pushl %eax movl 0x0004(%ebp), %eax movl %eax, g_Argc pushl %eax /* Register 초기화 : 꼭 필요한 과정은 아니지만 간혹 문제(Linux의 버그를 말하는 것이 아님)를 발생할수도 있어 초기화를 수행합니다. */ xorl %eax, %eax xorl %ebx, %ebx xorl %ecx, %ecx xorl %edx, %edx xorl %ebp, %ebp xorl %esi, %esi xorl %edi, %edi call main addl $4+4, %esp movl %eax, %ebx movl $1, %eax int $0x80 /* 이 이후의 코드가 실행된다면 이것은 Linux kernel이 정상이 아닙니다. 즉, 이 이후에 나오는 명령은 의미가 크게 없습니다. */ hlt popl %ebp ret .data g_Argc: .long 0 g_Argv: .long 0 # End of source }}}