【问题标题】:executing assembly within a function in c++在 C++ 中的函数内执行程序集
【发布时间】:2011-05-15 14:39:45
【问题描述】:
长 getesp() { __asm__("movl %esp,%eax"); } 无效的主要(){ printf("%08X\n",getesp()+4); }

为什么 esp 在设置堆栈帧之前指向值,它与下面的代码有什么区别?

无效的主要(){ __asm__("movl %esp,%eax"); }

【问题讨论】:

    标签: c assembly x86 inline-assembly


    【解决方案1】:

    在我做了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
    

    getesp 有一个pushl,它操纵esp 并通过内联和ebpeax 中获取操纵的esp

    调用函数来获取堆栈指针并将其放入main 肯定是不同的,并且相差 12 个字节(在这种特定情况下)。这是因为当您执行call 时会推送eip(如果不是段间,并且对于linux/unix 正常程序执行它只是eip)(需要引用),接下来在getesp 函数中还有另一个pushebp 之后堆栈指针减 4。因为 eipebp 是 4 个字节,所以现在总差值为 12 个字节。实际上我们可以在函数调用版本中看到。

    没有函数调用就没有eip 和其他esp 操作的推送,所以我们在主设置后得到esp 值。

    我对 AT&T 不满意,所以这里是 Intel 语法中的相同代码和下面的 Intex 语法 asm 转储。请注意,在 printf 调用 __asm__ 内的 main 值进入 a 没有推送或其他 esp 修改,因此, __asm__ 内 main 获得 esp 值,该值设置在主要由sub esp, 20 行。如上所述,我们通过调用 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
    

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-02-28
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多