繁体   English   中英

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

[英]cmp je/jg how they work in assembly

我想了解 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:
    ......

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

if (*x == 1)

应该

if (x == 1)

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

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

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

是的,这是正确的,除了在您的 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

英特尔 x86 JUMP 快速参考列出了x86程序集中可用的所有条件跳转,以及它们的条件(标志值)和它们的短跳转和长跳转的操作码。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM