cmp je / jg他们如何在装配中工作

时间:2012-09-30 21:30:11

标签: c assembly x86 conditional-statements cmp

我想了解cmp和je / jg如何在汇编中工作。我在谷歌上看到了一些例子,但我仍然有点困惑。下面我展示了我试图转换为C语言和相应C代码的汇编代码的一部分。它是以正确的方式实现还是我对cmp如何工作有错误的理解?

cmp    $0x3,%eax
je     A
cmp    $0x3,%eax
jg     B
cmp    $0x1,%eax
je     C


 int func(int x){


  if(x == 3)
    goto A;

  if (x >3)
    goto B;


  if(x == 1)
     goto C;

    A:
    ......

    B:
    ......

    C:
    ......

3 个答案:

答案 0 :(得分:5)

您正确理解cmp和je / jg是如何工作的,但您的C代码中有错误。这一行:

if (*x == 1)

应该是

if (x == 1)

Here是x86控制流指令的一个很好的总结。

此外,没有理由为相同的值重复cmp指令。执行完毕后,您可以多种方式测试结果,而无需重复比较。所以你的汇编代码应该是这样的:

cmp    $0x3,%eax
je     A
jg     B
cmp    $0x1,%eax
je     C

答案 1 :(得分:3)

是的,这是正确的,但在您的C代码中,您在第三个示例中有*x但在其他示例中有x,这是没有意义的。在汇编代码中没有对应的代码。

在C中,变量类型(有符号/无符号)是在声明变量时定义的,例如。 int xunsigned int x,但在汇编中,用于比较的有符号和无符号变量(无论是在内存中还是在寄存器中)之间的区别是通过不同的条件跳转来实现的:

对于签名变量:

jg  ; jump if greater
jl  ; jump if less
jge ; jump if greater or equal, "jnl" is synonymous
jle ; jump if less or equal, "jng" is synonymous

对于无符号变量:

ja  ; jump if above
jb  ; jump if below
jae ; jump if above or equal, "jnb" is synonymous
jbe ; jump if below or equal, "jna" is synonymous

Intel x86 JUMP quick reference列出x86程序集中可用的所有条件跳转及其条件(标志值)及其短跳和长跳的操作码。

答案 2 :(得分:2)

正如您可能已经知道的那样,处理器会在所谓的标记寄存器中跟踪上次操作期间发生的事情。 例如,如果操作溢出,或者结果为零等,则有一个标志.cmp助记符告诉处理器减去两个寄存器/寄存器和内存内容,它会更改正确的标志。 之后,您可以使用已完成的跳转来跳转。处理器检查标志是否等于,(检查零标志),或者它是否更小/更大(无符号的溢出标志和有符号数的溢出和符号标志)。