[英]carry flag in cmp instruction x86
我是x86的新手,我试图将较大的整数(位置4(%esp)和8(%esp))放入寄存器%eax中。 据我了解,我的cmp命令会将进位标志设置为1或零,然后adc将该标志传送到eax寄存器。 然后,我可以通过从esp偏移4 +标志* 4来获得所需的值。 除负值外,它似乎在所有情况下都有效,我有点困惑吗?
movl 4(%esp), %ecx
cmp 8(%esp), %ecx
movl $0, %eax
adc $0, %eax
movl 4(%esp, %esp, 4), %eax
ps我不允许跳/分支或快速的花样技巧。
与大多数两个补码表示CPU一样,x86实际上并不知道您的数字是否已签名。 您只需以您认为的方式对待他们。
当您进行比较时,您实际上是在进行“减法”并丢掉答案。 从两个数字的无符号减法中将进位位设置为“借位”。 如果要检查进位,则在进行比较后,实际上是在声明数字是无符号的。 因此,对于带符号的数字,您会得到错误的答案。
如果要比较两个带符号的数字,则需要查看差异的符号。 如果值足够大,则符号存在问题,因此差异会导致溢出,但是我们可以通过使用等于“跳转符号小于”(大多数x86汇编器中为JLT)的值来解决此问题。 。
因此,按照您的样式进行编码的简单方法是:
movl 4(%esp), %ecx
cmp 8(%esp), %ecx
movl $0, %eax
jlt L1
add $1, %eax
L1: movl 4(%esp, %esp, 4), %eax
但是您说您不允许使用jmp指令。 对您来说幸运的是,有一条指令实际上执行了“ jlt .. add $ 1”对所称为“ setge”的指令,但它仅将其答案放入AL中。 因此,在将条件插入最低字节之前,需要将movl $ 0的eax全部清零。 (指令集中的每个jcc都有一个setcc)。 所以这将工作:
movl 4(%esp), %ecx
cmp 8(%esp), %ecx
movl $0, %eax
setge %al ; use opposite condition than above jle
L1: movl 4(%esp, %esp, 4), %eax
甚至还有一条更方便的指令:mov conditional(cmov),如果某个条件(任何可能的jmp条件)为true,则它将值移动到寄存器。
movl 4($esp), %eax
movl 8($esp), %ecx
cmp %ecx, %eax
cmovge %ecx, %eax
OP的作业:查阅mov条件指令,以了解其工作原理。
(我不是AT&T汇编语言语法专家;上面可能有小错误)。
进位标志包含两个值的无符号比较的结果-以x86的说法是AE
(大于或等于)比较。 如果要进行带符号的比较,则需要使用GE
(大于或等于)比较,该比较将测试符号和溢出标志是否相等(进位标志无关)。 您可以使用setge
指令将其保存到寄存器中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.