开发者

executing assembly within a function in c++

    
long getesp() {  
    __asm__("movl %esp,%eax");  
    }  

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

why does esp points to value before the stack frame is setup and does it makes any difference between with the code below?

   
void main() {    
  开发者_开发知识库 __asm__("movl %esp,%eax");    
   } 


After i did a 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

The getesp has a pushl which manipulates the esp and gets the manipulated esp in eax with the inline and as well as in ebp.

Making a function call to fetch the stack pointer and getting it inside the main is definitely different, and it differs by 12 bytes (in this specific case). This is because when you execute the call pushes the eip (if not intersegment, and for linux/unix normal program execution it is only eip) (need citation), next inside the getesp function there is another push with ebp and after that the stack pointer is subtracted by 4. Because the eip and ebp are of 4 bytes, so the total difference is now 12 bytes. Which actually we can see in the function call version.

Without the function call there is no pushing of eip and other esp manipulation, so we get the esp value after the main setup.

I am not comfortable with AT&T so here is the same code in Intel syntax and an Intex syntax asm dump below. Note that in the printf call for the __asm__ inside the main value got into a there is no push or other esp modification so, the __asm__ inside main gets the esp value which was set in the main by the sub esp, 20 line. Where as the value we get by calling getesp is the (what you are expecting) - 12 , as described above.

The C Code

#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);
}

The output is in my case for the specific run:

BF855D00
BF855CF4

The intel syntax dump is:

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

I hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜