c - 需要帮助在 C 代码中编写汇编语言

标签 c assembly

我正在致力于将汇编语言转换为 C 程序。我知道在下面的函数中,有一个参数设置为 0,并将其与某个参数进行比较(我不确定这是什么,这就是我感到困惑的原因)。如果 x 小于或等于它所比较的​​值,则该函数将跳转到 f2,然后将 0 复制到局部变量中,但如果不是,则将 1 复制到局部变量中,并将其复制到返回的寄存器 a 中。我不明白前几行中的参数与什么进行比较。谁能指出我正确的方向?

这是语言:

     pushl    %ebp
     movl     %esp, %ebp
     subl     $4, %esp
     cmpl     $0, 8(%ebp)
     jle . f2
     movl     $1, -4(%ebp)
     jmp. f3  
 .f2:
     movl     $0, -4(%ebp)

 .f3:
     movl     -4(%ebp), %eax
     leave
     ret

我认为它在 C: 中应该是这样的:

         fn(int x)
         {
            x = 0;
           if    x    <=   ?   :
                int   y  =   0;
           else
                int y  = 1;
          }
          return y;

提前谢谢您

最佳答案

(首先,抱歉,我会翻译成 Intel 语法,我真的无法全神贯注于 AT&T)

    push ebp
    mov ebp,esp
    sub esp,4

这是通常的函数序言;保存基指针,将堆栈指针设置为基指针,在堆栈上为一个局部变量(后面称为 [ebp-4] )腾出空间;我们称这个变量为 int ret .

    cmp dword ptr[ebp + 8], 0

比较 ebp+8 处的值与 0 ,并相应地设置标志寄存器,以便以后任何条件跳转指令都可以根据比较结果进行操作。位置在ebp+8可能是一个 32 位函数参数( ebp+4 通常是函数的返回值);我们将此参数称为 int x .

    jle .f2
    mov dword ptr[ebp-4], 1
    jmp .f3  
.f2:
    mov dword ptr[ebp-4], 0
.f3:

这相当简单;如果在最后一次比较中,第一个操作数(AT&T 语法中的第二个操作数)结果小于或等于第二个操作数,则跳转到标签 .f2 ,否则直接走(并且在 mov 之后,跳转到 .f3 )。

最终结果是,如果 x<=0 , ret=0 ,否则ret=0 .

    mov eax,dword ptr[ebp-4]

此举reteax ,这是很多调用约定中保留返回值的位置。

    leave
    ret

这是标准函数尾声;它修复了ebpesp到之前的状态,然后 ret返回给调用者。

所以,整个事情可以归结为:

int f(int x)
{
    int ret;
    if(x<=0)
        ret=0;
    else
        ret=1;
    return ret;
}

或者,更简洁地说:

int f(int x)
{
    return x>0;
}
<小时/>

顺便说一句,总而言之,这看起来像 gcc 的输出禁用优化:编译我用 -m32 -c -S 编写的第一个函数我得到:

.LFE0:
    .size   g, .-g
    .globl  f
    .type   f, @function
f:
.LFB1:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $16, %esp
    cmpl    $0, 8(%ebp)
    jg  .L4
    movl    $0, -4(%ebp)
    jmp .L5
.L4:
    movl    $1, -4(%ebp)
.L5:
    movl    -4(%ebp), %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret

删除 cfi-directives 后等等,正是您发布的内容。

(添加 -O3 ,它肯定会变得更聪明:

movl    4(%esp), %edx
xorl    %eax, %eax
testl   %edx, %edx
setg    %al
ret

)

关于c - 需要帮助在 C 代码中编写汇编语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23598034/

相关文章:

C++ 二维阵列乒乓球板

assembly - 多态的代价

c - 哪个运算符更快(> 或 >=)、(< 或 <=)?

c++ - 是什么导致了这种格式字符串攻击?

assembly - 使用 div 和 mod 后打印编号 - MASM 不起作用

c - 在 PowerPC 上实现断点读/写

c++ - 如何实现综合基准?

c - 从以下代码中获取警告 "cast to pointer from integer of different size"

c - 是否可以将一个简单的代码块转换为一个结构?

c - 在Windows和Linux之间切换Eclipse中的C项目配置