2011-05-15 94 views
2
  
long getesp() { 
    __asm__("movl %esp,%eax"); 
    } 

    void main() { 
    printf("%08X\n",getesp()+4); 
    } 

爲什麼在堆棧幀設置之前esp指向value,並且它與下面的代碼有什麼區別?在C++中執行彙編函數

 
void main() {  
    __asm__("movl %esp,%eax");  
    } 

回答

3

後,我做了一個gcc -S file.c

getesp: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $4, %esp 
#APP 
# 4 "xxt.c" 1 
    movl %esp,%eax 
# 0 "" 2 
#NO_APP 
    leave 
    ret 


main: 
    leal 4(%esp), %ecx 
    andl $-16, %esp 
    pushl -4(%ecx) 
    pushl %ebp 
    movl %esp, %ebp 
    pushl %ecx 
    subl $20, %esp 
    call getesp 
    addl $4, %eax 
    movl %eax, 4(%esp) 
    movl $.LC0, (%esp) 
    call printf 
    addl $20, %esp 
    popl %ecx 
    popl %ebp 
    leal -4(%ecx), %esp 
    ret 

getesppushl其操縱esp,並與在線獲取eax操縱esp和以及在ebp

進行函數調用來獲取堆棧指針並在main中得到它肯定是不同的,並且它相差12個字節(在這個特定情況下)。這是因爲當你執行call時推動eip(如果不是段間,並且對於linux/unix正常程序執行它只是eip)(需要引用),接下來在getesp函數中有另一個pushebp,之後堆棧指針減去4.因爲eipebp是4個字節,所以總差值現在是12個字節。實際上我們可以在函數調用版本中看到。

沒有函數調用eipesp沒有推動操作,所以我們得到主設置後的esp值。

我不熟悉AT & T所以這裏是Intel語法和下面的Intex語法asm dump中的相同代碼。需要注意的是在主值內printf呼籲__asm__陷入a沒有推或其他esp修改的話,裏面主要的__asm__得到這是在主要由sub esp, 20線設置esp值。如上所述,通過調用getesp得到的值就是(你所期望的) - 12。

C代碼

#include <stdio.h> 

int a; 

long getesp() { 
__asm__("mov a, esp"); 
} 

int main(void) 
{ 

    __asm__("mov a,esp"); 
    printf("%08X\n",a); 

    getesp(); 
    printf("%08X\n",a); 
} 

輸出是在我的案件的具體運行:

BF855D00 
BF855CF4 

英特爾語法轉儲:

getesp: 
    push ebp 
    mov  ebp, esp 
    sub  esp, 4 
#APP 
# 7 "xt.c" 1 
    mov a, esp 
# 0 "" 2 
#NO_APP 
    leave 
    ret 


main: 
    lea  ecx, [esp+4] 
    and  esp, -16 
    push DWORD PTR [ecx-4] 
    push ebp 
    mov  ebp, esp 
    push ecx 
    sub  esp, 20 
#APP 
# 12 "xt.c" 1 
    mov a,esp 
# 0 "" 2 
#NO_APP 
    mov  eax, DWORD PTR a 
    mov  DWORD PTR [esp+4], eax 
    mov  DWORD PTR [esp], OFFSET FLAT:.LC0 
    call printf 
    call getesp 
    mov  eax, DWORD PTR a 
    mov  DWORD PTR [esp+4], eax 
    mov  DWORD PTR [esp], OFFSET FLAT:.LC0 
    call printf 
    add  esp, 20 
    pop  ecx 
    pop  ebp 
    lea  esp, [ecx-4] 
    ret 

我希望這有助於。