2013-12-20 2 views
1

스택에 대해 자세히 알고 싶습니다. 특히 매개 변수가있는 함수가 호출되면 어떻게됩니까? 이를 위해, 나는 다음과 같은 코드 쓰기 :매개 변수가있는 함수를 사용하여 스택에서 ebp 및 esp의 동작

#include <stdio.h> 
    int sum(int d, int e, int f){ 
     int result = d + e + f; 
     return result; 
    } 

    int main(void){ 
    int a = 5; 
    int b = 4; 
    int c = 2; 

    int erg = sum(a,b,c); 
    printf("Result is: %d", erg); 

    } 

을 나는 (처음에는이 부분을 이해하기 원하기 때문에 내가에만 main 기능의 일부를 추가합니다) 다음 어셈블리 코드를 얻을 :

push ebp, 
    mov ebp, esp 
    and esp, -16 
    sub esp, 32 
    mov DWORD PTR[esp+28], 5 
    mov DWORD PTR[esp+24], 4 
    mov DWORD PTR[esp+20], 2 
    mov eax, DWORD PTR[esp+20] 
    mov DWORD PTR[esp+8], eax 
    mov eax, DWORD PTR[esp+24] 
    mov DWORTD PTR[esp+4], eax 
    mov eax, DWORD PTR[esp+28] 
    mov DWORD PTR[esp], eax 
    call sum 
    ........ 
    ........ 

이 부분에 대해서는 나 자신을 위해 약간의 스케치를 그립니다. 제발 좀보세요 :) 내 질문 : 그 시점에서 내 ebp은 무엇입니까? 어셈블러 코드의 2 행 때문에 같은 위치에 있어야합니다 ([esp])?

이제 제 2의 질문에 이어지는 합계 기능의 부분.

push ebp 
    mov ebp, esp 
    sub esp, 16 
    mov eax, DWORD PTR[ebp+12] 
    mov edx, DWORD PTR[ebp+8] 
    mov edx, eax 
    ------------ 

그래서, 나는 우리가 [eb+12][ebp+8] 항상 우리의 매개 변수를 찾을 수 있다는 것을 배웠습니다 :

그래서 여기에의 어셈블리 코드입니다. 내가 그 esp = ebp을 가정하면 을하고 내 스케치를 보면 그때 [esp+12] 아무것도이나 지금 [ebp+12]이 없다는 것을 참조 : 그래서 내 질문에 지금 (나는 간단하게 원하기 때문에 나는 세 번째 매개 변수를 생략). 그러나 그럼에도 불구하고, 그것은 사용됩니다. 어떻게 상상할 수 있습니까?

나를 도와 줄 사람이 있습니까? 나는 많은 논문을 읽었지 만 아무도 이런 것들을 스케치하지 않는 것 같습니다. 그 때문에, 그것을 이해하는 것은 매우 어렵습니다.

감사합니다.

enter image description here

답변

4

espebp는 명령 mov ebp, esp 직후에만 값이 동일한 상기 제 1 기능 실행 중 :

여기에 내 스케치이다. 그 후 and esp, -16esp의 하위 4 비트 (최하위 니블)를 0으로 제하고 esp의 최하위 비트가 이미 0이 아닌 경우 espebp이 발산합니다. 그런 다음 sub esp, 32esp에서 32를 빼고 여기에서 espebp이 분기됩니다. 그런 다음 두 번째 질문에 대한

push ebp     ; esp = esp - 4; [esp] = ebp. 
mov ebp, esp    ; ebp = esp. create the stack frame. 
and esp, -16    ; make lowest 4 bits of esp zeros, for alignment. 
sub esp, 32    ; esp = esp - 32. make space for local variables. 
mov DWORD PTR[esp+28], 5 ; a = 5 
mov DWORD PTR[esp+24], 4 ; b = 4 
mov DWORD PTR[esp+20], 2 ; c = 2 
mov eax, DWORD PTR[esp+20] ; eax = c (eax = 2) 
mov DWORD PTR[esp+8], eax ; [esp+8] = dword 2 
mov eax, DWORD PTR[esp+24] ; eax = b (eax = 4) 
mov DWORTD PTR[esp+4], eax ; [esp+4] = dword 4 
mov eax, DWORD PTR[esp+28] ; eax = a (eax = 5) 
mov DWORD PTR[esp], eax ; [esp] = dword 5 
call sum     ; the above lines define the parameters for the 
          ; function sum, that is called now. 

:

push ebp     ; esp = esp - 4; [esp] = ebp. 
mov ebp, esp    ; ebp = esp. 
sub esp, 16    ; esp = esp - 16. create space for local variables. 
          ; at this point: 
          ; [ebp] == old value of ebp. 
          ; [ebp+4] == return address pushed by call, 
          ;    to be used by the next ret. 
          ; [ebp+8] == dword 5 (a) 
          ; [ebp+12] == dword 4 (b) 
          ; [ebp+16] == dword 2 (c) 
mov eax, DWORD PTR[ebp+12] ; eax = 4 
mov edx, DWORD PTR[ebp+8] ; edx = 5. gets overwritten by the next instruction.   
mov edx, eax    ; edx = eax = 4 

esp == ebp을 가정하지 마십시오. 이 두 번째 함수에서도 sub esp,16 명령을 실행하면 espebp이 분기됩니다. 디버거를 사용하는 법을 배우십시오 (예 : GDB). 코드를 한 단계 건너 뛰고 레지스터 값 (특히 esp)과 각 명령어 다음의 메모리를 따르십시오. 또한 위에서 설명한대로 코드를 디버깅 할 수도 있지만, 어셈블리 초보자라면 디버거를 사용하는 것이 일반적으로 훨씬 쉽고 오류가 발생하기 쉽습니다.

0

다음은 매개 변수를 사용하여 루틴을 호출 할 때 스택, 스택 프레임, ebp 및 esp에서 발생하는 상황에 대한 설명입니다. 도움이되기를 바랍니다. What is stack frame in assembly?

관련 문제