Hello World!

배병일 2010.04.21 15:13 조회 수 : 5069

http://yris.thoth.kr/?mid=blog&document_srl=291453 를 보면서 간단한 헬로월드 코드를 나름 정리해봤습니다.


#include <stdio.h>


int main()

{

      printf("Hello World!n");

      return 0;

}



push        ebp        // ebp 는 함수 호출시 그 순간의 esp 를 저장하고 있다가 함수가
                              // 리턴하기 직전에 다시 esp 에 값을 되돌려주어 스택이
                              // 깨지지 않도록 한다. <<- stack frame 기법
                              // push : 스택에 저장 명령
mov         ebp,esp   // ebp 에 esp(스택메모리주소를 가리킴) 를 저장
sub          esp,0C0h // sub 는 캐리를 포함하지 않은 뺄셈
                                // Carry는 덧셈, 뺄셈, 곱셈, 나눗셈들에서 32bit (혹은 8bit)연산 도중에 그것을
                                // 초과할 경우 Carry가 발생한 것을 저장하기 위한 공간
                                // 0c0h : 사용 스택 크기 , 192 바이트를 잡음.
                                // 스택은 위에서 아래로 자라므로 sub(뺄셈) 임.
                                         
// ebx, esi, edi 사용 후 복원을 위해 스택에 저장   
push        ebx        // ebx : ds 세그먼트안의 데이터(데이터세그먼트주소)를 가리키는 포인터
push        esi        // esi : 문자열 연산에 대한 소스 포인터, 메모리 복사에 사용
push        edi        // edi : 문자열 연산에 대한 목적지 포인터, 메모리 복사에 사용
lea         edi,[ebp-0C0h] // lea : 메모리의 오프셋값을 레지스터로 로드하는 명령
                             // edi 에 ebp-0c0h 주소값 (스택이 더 자랄 경우 시작점) 저장
mov         ecx,30h            // ecx 에 30h 넣음. ecx 는 반복 카운터로 수행시마다 1씩 감소
mov         eax,0CCCCCCCCh // eax 레지스터(보통 리턴값을 담음)을 0CCCCCCCCh로 초기화
rep stos    dword ptr es:[edi] // rep : 이후에 나오는 명령을 cx가 0이 될때까지 반복
                                               // stos : al 또는 ax 를 es:di 가 지시하는 메모리에 저장
                                               // eax 의 값(0ccccccch) 을 edi 로 복사 30h 만큼 반복.
mov         esi,esp            // esi 에 스택메모리 주소를 담는다.
push        offset string "Hello World!n" (41573Ch) // 헬로월드 문자열 오프셋을 푸시, 프린트함수의 인자로.

                                                                              // char *buf = "Hello World!n" 같이 하고 buf를 넘기면

                                                                              // 데이터 세그먼트의 문자열을 가리키는 주소를 변수 buf 에 mov 하고

                                                                              // 이것을 넘김

call           dword ptr [__imp__printf (4182BCh)] // 함수호출
add          esp,4            // add : 캐리 없는 덧셈
                                     // 함수 호출을 위해서 push 했던 데이터가 호출 후엔 더이상 필요가 없다.                                                                                 // pop 을 안하는 이유는 pop 이 add 에 비해 오버헤드가 크고
                                     // 이경우 그냥 버리는 데이터 이기 때문.. 값이 필요하다면 pop 해야함.
                                     // 함수를 실행을 위해 늘어난 스택을 보정하기 위해 add 를 하는 것임
                                     // printf 는 cdecl 호출 규약을 따르므로 main 에서 스택을 정리함

cmp         esi,esp            // 위에서 esi 에 esp 를 담아 놨었음
                                      // cmp : 두개의 오퍼랜드를 비교한다.   
                                      // esi 가 크면 SF 를 0으로 ebp 가 작으면 1로
                                      // 같으면 ZF 를 1로 설정
call        @ILT+310(__RTC_CheckEsp) (41113Bh) // 런타임 체크 호출, esp 유효성 확인


xor         eax,eax        // 0을 만드는 방법.
                                   // mov eax, 0 은 5바이트나 먹어버림.
                                  // 0을 만드는 방법에는 MOV r1,0    XOR r1,r1   SUB r1,r1   AND r1,0
                                  // 들이 있음
pop         edi 
pop         esi 
pop         ebx            // 스택에 백업 떠놓은 edi , esi, ebx 레지스터값 복원
add         esp,0C0h   // esp 도 스택잡았던 오프셋만큼 더해서 복원
cmp         ebp,esp    // 함수 들가기전 스택 주소 저장했던 ebp 와
                                // 함수 탈출 시점에서 스택 주소 esp 비교
call        @ILT+310(__RTC_CheckEsp) (41113Bh) // 런타임 체크 esp 유효성 확인
mov         esp,ebp  // ebp 를 esp 로 옮겨 스택 되돌림
pop         ebp    // ebp 를 꺼내어 이전으로 복원
ret    // 리턴

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 커널 스터디 관련 Q&A 게시판 입니다. [5] woos 2016.04.09 2197
125 커널7차(x86) B 분들 메일 확인해보세요. [5] 배병일 2010.05.02 2750
124 [5월8일] 스터디 참석 여부 댓글로~^^ [3] 나무꾼 2010.05.02 1955
123 5월 1일 스터디 내용 및, 진행방향 [2] file 최문규 2010.05.02 2981
122 스터디 존속 여부 [2] 이재훈 2010.05.01 1959
121 as86(1) - Linux man page 입니다. 김민석 2010.04.30 36679
120 as86 어셈으로 부팅 코드 관련 문서 입니다. 김민석 2010.04.30 6114
119 컥; 저번에 이 문서도 빼먹었네요; file 최문규 2010.04.30 3459
118 어떻게 공부하셨나요?? [3] 김이현 2010.04.30 2879
117 제임스몰리의 커널개발 튜토리얼 [1] 배병일 2010.04.30 2833
116 도움이 될만한 사이트 배병일 2010.04.29 2851
115 Windows NT 에서의 시스템 콜 [3] 박한범 2010.04.27 2245
114 4월 24일 스터디 내용 [2] file 최문규 2010.04.26 2711
113 OS커널의 구조와 원리 책 목차 [1] 배병일 2010.04.26 3272
» Hello World! [1] 배병일 2010.04.21 5069
111 g어셈블러, n어셈블러 관련 차이점 배병일 2010.04.20 3010
110 소스올리실때의 팁(?!) [2] 최문규 2010.04.19 2863
109 커널 동기화 배병일 2010.04.19 3661
108 IA-32 Register 기본 [1] 배병일 2010.04.19 2701
107 do_fork(), sys_clone()... 분석-수정본 [7] 최문규 2010.04.18 10837
106 4월 17일 스터디 Issue list 김두균 2010.04.18 2757
XE Login