assembly - 减数较大时如何设置进位标志?

标签 assembly x86 masm cpu-architecture digital-logic

我知道只要被减数小于减数并且需要借位,就会在 SUB 期间设置进位标志,但无法找到任何更详细的解释。

既然减法实际上只是加了补码,那么CPU如何知道减数更大并且发生了借位呢?

我唯一能想到的是,每当将减数转换为其 2 的补码时,进位标志可能会在 SUB 期间自动设置。然后除非发生另一个进位(当被减数大于减数时在加法过程中应该发生)将其重新关闭,否则它会保持打开状态。

还是我离得远了?

最佳答案

您似乎混淆了进位和溢出标志。
进位标志检查无符号溢出,溢出标志检查有符号溢出。
其工作原理是在减法之前比较(无符号)数字,如果 b > a,则设置 CF。
如果第一个操作数的符号发生变化,则设置溢出。

在减法过程中,CPU 不关心操作数是否为负。
如果无符号基数小于要减去的无符号数,则会发生进位。

例如(刚刚在我的调试器的 CPU View 中进行了测试)

 0 - -1 = 1  ->> CF = 1, because 0xFFFFFFFF > 0  
10 - -1 = 11 ->> CF = 1, same reason
-2 -  4 = -6 ->> CF = 0, because 0x4 < 0xFFFFFFFE  

请记住,在有符号算术中,这些结果是正确的,但在无符号算术中,它们“完全”偏离,因此 CF=1。

进位标志不知道也不关心符号,它(仅)用于无符号溢出。 请记住,CPU 无法知道您是否要执行有符号或无符号操作。由应用程序测试相关标志来解释结果,这就是CPU提供两组溢出标志的原因。

以下是最常见标志及其功能的列表:

code | descripton     |name     | When set
---+++----------------+---------+-------------------
CF  unsigned overflow  Carry      If unsigned over-/underflow occurs
OF  signed overflow    Overflow   If sign bit (MSB) flips
SF  Sign flag          Sign       If MSB is set, i.e. is result is negative
ZF  Zero flag          Zero       If Result is zero

这两个标志都没有太多“智能”。
您需要记住,这些标志是在晶体管供应短缺时设计的。

关于2的补码
2 的补码被设计为加法和减法不需要知道从正数到负数的转换。
您可以直接进行加减操作,无需关心操作数或结果是正数还是负数。
唯一需要注意的是溢出,这正是进位标志测试的内容。

如果您在哪里使用普通反转(即 1 的补码)作为负数,那么您需要围绕加法和减法采取各种保护措施;这就是2的补码被普遍使用的原因。

进一步阅读
http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt
谢谢彼得

关于assembly - 减数较大时如何设置进位标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41841768/

相关文章:

c - 替换内联汇编代码

assembly - x86除法异常返回地址

程序集:此程序中 movl data_items(,%edi,4), %eax 的目的是什么

assembly - 在 NASM 汇编代码中遍历数组

转换帮助 : __asm__ __volatile__

c - 如何在 Mac OS X 上构建包含入口点的 C 程序?

c - MASM64,Visual studio 2015 C 程序,具有单独文件中的汇编功能

assembly - 错误 A2008 : syntax error :

c++ - 在 Assembly 中添加四个以上的参数

assembly - 有关 VGA 和 putpixel intel x86 asm AT&T 语法的帮助