我正在努力了解装配能够解决难题。但是我遇到了以下说明:
0x0000000000401136 <+44>: cmpl $0x7,0x14(%rsp)
0x000000000040113b <+49>: ja 0x401230 <phase_3+294>
我认为它的作用是: 0x14(%rsp)的值是-7380。根据我的理解,cmpl比较unsigned。还执行跳转。 那就是(无符号)-7380&gt; 7 (未签名)7380&gt; 7 - &GT;跳
我实际上不希望它跳。但这是正确的解释吗?我在翻开争论吗?
另外,如果你对如何操纵这个跳跃有任何建议!
答案 0 :(得分:16)
根据我的理解
cmpl
比较无符号。
它在某种程度上同时做到了。
有符号与无符号的区别在于跳转指令的使用。
对于>
,ja
表示无符号,jg
表示签名(如果超过则跳转,如果更大则跳转)。
对于<
,jb
表示无符号,jl
表示签名(如果低于此值则跳转,如果更少则跳转)。
确切地说,这是几个跳转命令的含义:
对于无符号比较:
JB/JNAE (CF = 1) : Jump if below/not above or equal JAE/JNB (CF = 0) : Jump if above or equal/not below JBE/JNA (CF = 1 or ZF = 1) : Jump if below or equal/not above JA/JNBE (CF = 0 and ZF = 0): Jump if above/not below or equal
签名比较:
JL/JNGE (SF <> OF) : Jump if less/not greater or equal JGE/JNL (SF = OF) : Jump if greater or equal/not less JLE/JNG (ZF = 1 or SF <> OF): Jump if less or equal/not greater JG/JNLE (ZF = 0 and SF = OF): Jump if greater/not less or equal
答案 1 :(得分:2)
只是为了澄清@glglgl 的优秀答案添加一个额外的细节是“cmpl”中的“l”是一个 operation suffix 表示操作是在一个长数(32 位整数或 64 -位浮点数)。
答案 2 :(得分:1)
我认为x86实际上并没有一个名为CMPL
的指令。它可能是汇编语法的一部分,用于给出操作数或其他内容的提示(例如JZ
和JE
相同)。
从英特尔手册中了解它的作用:
比较第一个源操作数和第二个源操作数并设置 根据结果,EFLAGS寄存器中的状态标志。比较是 通过从第一个操作数中减去第二个操作数然后设置来执行 状态标志的方式与SUB指令相同。什么时候立即 value用作操作数,它被符号扩展为第一个操作数的长度。
由于数字的二进制补码表示,因此隐含地给出了符号。
如何操纵跳跃?如果你确定跳转应该与它正在做的完全相反,你只需要将JA
更改为JBE
。