【发布时间】:2017-11-16 15:28:48
【问题描述】:
我正在通过Richard Detmer's Assembly Language book 工作。
第一章说:
A borrow occurs in the subtraction a - b when b is larger than a as unsigned numbers. Computer hardware can detect a borrow in subtraction by looking at whether a carry occurred in the corresponding addition. If there is no carry in the addition, then there is a borrow in the subtraction. If there is a carry in the addition, then there is no borrow in the subtraction.
进位标志是EFL寄存器的第0位。
假设我们要执行 195D - 618D = -423D 作为减法运算。有借位,因此不应设置进位标志。
以下 asm 代码编译并运行,但在 sub rax, 618 之后,确实设置了进位标志。
对应的加法是 00C3h + FD96h,这不涉及进位,因为最终的成对加法是 0 + F,没有进位,因此最终成对加法没有进位。
.DATA
number QWORD 195
sum QWORD ?
.CODE
main PROC
mov rax, number ; 195 to RAX
sub rax, 618 ; subtract 618
;at this point, however, the carry flag is indeed set to 1. Why is this?
mov sum, rax ; sum to memory
mov rax, 0 ; return code
ret ; exit to operating system
main ENDP
END
我不清楚这是怎么回事。
任何帮助将不胜感激。
【问题讨论】:
-
这只是一个简单的误解,对 SUB 的借用 确实 由进位标志发出信号。没有专用的“借”标志,进位标志可以完成这两项工作。没有歧义,因为您知道您只是执行了 ADD 还是 SUB。
-
@HansPassant 是的,这是我的疏忽。后面的文中确实讲了add和sub对flags的影响,你说的确实很清楚了。
-
有趣的事实:在一些非 x86 架构(如 ARM)中,进位标志仍然是进位,而不是减法借位。所以它基本上与 x86 使用它的方式相反。见en.wikipedia.org/wiki/Carry_flag#Carry_flag_vs._borrow_flag。这就是为什么 ARM 有一条
sbc指令(带有进位的子指令)而不是 x86 的sbb(带有借位的子指令)。