汇编 x86-64 为子指令设置进位标志

Assembly x86-64 setting carry flag for sub instruction

我正在完成 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

我不清楚这是怎么回事。

任何帮助将不胜感激。

首先理解有无符号整数运算(其中溢出由进位标志表示)和有符号整数运算(其中溢出由溢出标志表示)。

无符号和有符号整数运算使用相同的加法和减法指令。唯一的区别是您之后测试的标志以及您如何解释结果(例如 -0x0000423D 或 0xFFFFBDC3)。

借位也由进位标志指示。这意味着只要发生​​无符号整数溢出,就会发生借位。对于0x0000195D - 0x0000618D有无符号整数溢出(无符号整数不能为负),所以会设置进位标志(但没有有符号整数溢出,所以不会设置溢出标志) .结果将是 0xFFFFBDC3 或 -0x0000423D,具体取决于结果应该是有符号的还是无符号的。