2012-09-30 40 views
1

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

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

您可以正确理解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 
+0

对'*'的感谢,忘记了:) – FranXh

3

是的,这是正确的,但在C代码,你必须在第三个例子*xx在其他国家,这是没有意义的。在你的汇编代码中没有相应的代码。

在C中,变量类型(有符号/无符号)是在声明变量时定义的,例如。

对于有符号的变量::

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 

对于无符号变量int xunsigned int x,但在组件符号和无符号的变量之间的区别(它们是在存储器或寄存器中),用于比较由不同的条件跳转制成:

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装配所有可用的条件跳转,他们的条件(标志值)和他们的SH一起操作码ort和长跳跃。

2

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

+0

进位标志用于表示无符号溢出。溢出标志用于表示签名溢出。为了比较,检查标志的组合:CF和ZF用于带符号的无符号,SF,OF和ZF。如果你不确定,你可以在手册中快速检查一遍。 –

相关问题