executing assembly within a function in c++

后端 未结 1 1392
后悔当初
后悔当初 2021-01-22 09:41
    
long getesp() {  
    __asm__(\"movl %esp,%eax\");  
    }  

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

why does esp points to value be

1条回答
  •  -上瘾入骨i
    2021-01-22 10:06

    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 
    
    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 讨论(0)
提交回复
热议问题