【发布时间】:2022-01-10 23:01:52
【问题描述】:
晚安。我正在组装实验室工作。我必须比较 3 个数字 -8、-2 和 11 以获得最大的。我将它们翻译成附加代码并以十六进制表示法表示。所以我得到了错误的答案,因为 -2 = FE > 11 = B。问题是如何正确比较这些数字? 我用的是 nasm,x86。
【问题讨论】:
晚安。我正在组装实验室工作。我必须比较 3 个数字 -8、-2 和 11 以获得最大的。我将它们翻译成附加代码并以十六进制表示法表示。所以我得到了错误的答案,因为 -2 = FE > 11 = B。问题是如何正确比较这些数字? 我用的是 nasm,x86。
【问题讨论】:
比较指令以及几乎所有算术指令都会修改状态寄存器中的一组标志。
标志的修改独立于指令的意图——例如无论(罕见)需要检查该标志的状态,奇偶标志或辅助标志都会被修改。
当-2和11比较,或者-2减去11时,处理器实际上并不知道-2是负数;而是计算 0xfe - 0x0b,它不会溢出,因此 CarryFlag == 0。同样因为结果不为零,ZeroFlag == 0 也是如此。而且由于 0xFE 的符号与 0x0b 不同,OverflowFlag == 0 也是。
所有这些 OF、ZF、CF 的不同组合映射到更高级别的抽象,例如unsigned <= unsigned、any != any、signed > signed。在英特尔架构中,“低于/高于”指的是无符号比较,“更大/更少”指的是有符号比较——同一组标志也可以指多个抽象,例如JC(参见http://unixwiz.net/techtips/x86-jumps.html)
您可能需要的带符号比较子集要么是 JG,要么是补码 JNG,它代表 Jump Not Greater,等于 JLE 或 Jump Less 或 Equal。
除了条件分支之外,x64 指令集还支持寄存器的条件设置/移动,armv7 允许条件执行大多数指令,armv8 允许条件执行一些有趣的指令序列(如a = b iff LessThan, else a = c + 1)。
【讨论】: