x86 assembly: ADD/SUB/INC/DEC without overflow and branching
在x86 ASM中,是否可以在不分支的情况下进行加法或减法来禁止溢出?因此,例如,从0x01减去0x02时,它将设置为0x00而不是0xFF。
我希望这可能是不可能的,所以我也想回答这个问题的一种更严格的形式,其中仅添加/减去0x01。我有个想法(OF是溢出标志):
1 2 | dec eax add eax,OF |
我不了解其他体系结构,但是对于i386,我无法为此找到操作码,因为显然标记不能解释为整数,不能用于算术运算。我找到了一个有效的解决方案,但仅当未使用较高字节时才对最低字节进行处理:
1 2 3 | dec ax sub al,ah xor ah,ah |
是否有更好的方法可以做到这一点,也许这也适用于更一般的情况?
在加1的情况下(使用
或者考虑使用SSE,它支持在单个指令中使用饱和整数算术运算。
您可以在较新的处理器上使用
请参阅http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/ vc35.htm
但是:
I had an idea that goes like this (OF being the overflow flag)
这不是您想要的溢出标志;表示该值溢出了使用2的补码可表示的范围(因此对于16位字值,如果该值小于-32768或大于32767,则溢出)。您似乎正在使用无符号数字(并且希望钳位为0),所以您需要的是进位标志。
例如,如果有进位(例如,结果从0到0xFFpackage),则可以使用
1 2 3 | sub ax, 1 xor bx, bx cmovc ax, bx |
这在减去任何值时有效。但是,事实证明,如果您只想递减,则有一种更简单的方法。您可以减去1,然后使用精确执行以下操作的指令加0进位:
1 2 | sub ax, 1 adc ax, 0 |
请注意,您不能使用
使用其他方式(加法),可以使用
1 2 3 | add ax, 1 mov bx, 0FFFFh cmovc ax, bx |