简体   繁体   中英

Carry Flag Assembly Language

Why is the Carry Flag set at 255 in this code

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

Maybe I am getting Overflow and carry mixed up, but since 1111 1111 is 255 in binary, shouldn't the carry only be set at 256?

There are two flags used to track when a value overflows .

One is the unsigned overflow, CF, and the other is the signed overflow OF.

The CF flag is set when you do an addition that goes over the maximum value a register can hold. In your case any addition that goes over 255.

For subtractions, same thing, the other way around. If you subtract and it goes under 0, then you get a carry.

The CF flag allows you to do additions on very large numbers without the need for specialized code:

add eax, ebx
adc ecx, edx

This adds two 32 bit numbers together (eax and ebx) and then another set of 32 bit numbers (ecx, edx) taking the carry in account. The result is ebx/edx representing a 64 bit number. You can use that for numbers of any size (ie you could write code to add two numbers of 1024 bits each.)

If your number is unsigned, you could add a jc overflow at the end, if it jumps, then you have an overflow (your number requires 65 bits after the addition.)

The OF flag is always set, however, it is generally only used on the last addition to know whether you had an overflow in the event your number is signed. If your number is always unsigned, then OF is never used in your code (obviously, the processor always set OF no matter what since it does not know whether you are working with a signed or unsigned number.)

So in our previous addition, you would do:

add eax, ebx
adc ecx, edx
jo overflow

When the jump to overflow happens, your 64 bit addition does not fit a 64 bit number. You would need 65 bits. That can be used to generate an exception and let the user know that his math is incorrect. The OF flag, of course, would work on AL in which case that value is viewed as a number between -128 and +127. If an add generates a number larger than 127, or a subtract a number smaller than -128, then OF gets set.

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM