进位标志汇编语言

Carry Flag Assembly Language

为什么在这段代码中Carry Flag设置为255

INCLUDE Irvine32.inc
.data
.code
main PROC

;adding 1 to 255 rolls AL over to zero:
mov al,255
add al,1    ; AL=0, CF=1 (unsigned overflow)
call DumpRegs

;subtracting larger number from smaller:
sub al,1    ; AL=255, CF=1
call DumpRegs

;subtracting 1 from 255
sub al,1    ; AL=254, CF=0
call DumpRegs

exit
main ENDP
END main

也许我把溢出和进位搞混了,但是由于 1111 1111 在二进制中是 255,进位不应该只设置为 256 吗?

nasm 语法:

mov al,255 子 al,1

mov al,254 子 al,1

mov al,1 子 al,255

mov al,1 子 al,254

我得到 0,0,1,1 的 CF

您期望的是什么?减法实现为反转并加 1,你补充第二个数字并进位是 1 而不是零。 0xFF + 0xFE + 1 = 0x1FE,作为 x86 上的减法,它是一个借位,所以进位对于一个 sub 是反转的。所以进位标志是0。0xFE + 0xFE + 1也是如此。但是对于0x01 + 0x00 + 1 = 0x002,0的进位变为1的进位标志。0x01 + 0x01 + 1 = 0x003 0的进位变为进位1 的标志。

你确定这些是斧头的价值吗?

当值溢出时,有两个标志用于跟踪。

一个是无符号溢出,CF,一个是有符号溢出OF。

当您进行的加法运算超过了寄存器可以容纳的最大值时,就会设置 CF 标志。在您的情况下,任何超过 255 的加法。

对于减法,同样的事情,反之亦然。如果你减去它小于 0,那么你得到一个进位。

CF 标志允许您在不需要专门代码的情况下对非常大的数字进行加法运算:

add eax, ebx
adc ecx, edx

这会将两个 32 位数字(eax 和 ebx)相加,然后将进位考虑在内的另一组 32 位数字(ecx,edx)。结果是 ebx/edx 代表一个 64 位数。您可以将它用于任何大小的数字(即您可以编写代码来添加两个 1024 位的数字。)

如果你的数字是无符号的,你可以在末尾加一个jc overflow,如果跳了,那就是溢出了(你的数字加完后需要65位。)

OF 标志始终设置,但是,它通常仅在最后一次添加时使用,以了解在您的号码被签名的情况下是否发生溢出。如果您的数字始终是无符号的,那么 OF 永远不会在您的代码中使用(显然,处理器总是设置 OF 无论如何,因为它不知道您使用的是有符号数字还是无符号数字。)

所以在我们之前的添加中,你会做:

add eax, ebx
adc ecx, edx
jo overflow

当发生溢出跳转时,您的 64 位加法不适合 64 位数字。您将需要 65 位。这可用于生成异常并让用户知道他的数学不正确。当然,OF 标志适用于 AL,在这种情况下,该值被视为 -128 和 +127 之间的数字。如果加法生成大于 127 的数字,或减法生成小于 -128 的数字,则设置 OF。