-1

为什么此代码中的进位标志设置为 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 吗?

4

2 回答 2

2

有两个标志用于跟踪值何时溢出

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

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

对于减法,同样的事情,反过来。如果你减去它并且它低于 0,那么你会得到一个进位。

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

add eax, ebx
adc ecx, edx

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

如果您的号码是无符号的,您可以jc overflow在末尾添加 a,如果它跳转,那么您有一个溢出(您的号码在添加后需要 65 位。​​)

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

所以在我们之前的补充中,你会这样做:

add eax, ebx
adc ecx, edx
jo overflow

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

于 2015-07-27T21:21:37.513 回答
1

nasm syntax:

mov al,255 sub al,1

mov al,254 sub al,1

mov al,1 sub al,255

mov al,1 sub al,254

I get CFs of 0,0,1,1

which is what you would expect right? subtraction is implemented as invert and add 1, you ones complement the second number and carry in is a 1 instead of a zero. 0xFF + 0xFE + 1 = 0x1FE, being a subtract on an x86 it is a borrow so the carry out is inverted for a sub. so carry flag is a 0. same goes for 0xFE + 0xFE + 1. but for 0x01 + 0x00 + 1 = 0x002 carry out of 0 becomes a carry flag of 1. 0x01 + 0x01 + 1 = 0x003 carry out of 0 becomes a carry flag of 1.

are you sure those are the values for ax going in?

于 2015-07-27T21:06:06.077 回答