3
.data
val1 BYTE 10h
val2 WORD 8000h
val3 DWORD 0FFFFh
val4 WORD 7FFFh

If val2 is incremented by 1 using the ADD instruction, what will be the values of the Carry and Sign flags?

If val4 is incremented by 1 using the ADD instruction, what will be the values of the Over- flow and Sign flags?

I answered both and got them both wrong. Why is the answer what it is?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user3682802
  • 89
  • 1
  • 2
  • 8
  • 1
    _"I answered both"_. And _what_ did you answer? – Michael Jun 02 '14 at 08:28
  • The first question I said both were 0 because val2 is a unsigned byte and adding one wouldn't make it negative. The answer says the Sign Flag is 1. – user3682802 Jun 02 '14 at 08:31
  • The second question I said 0 for both again. The answer says both were 1. – user3682802 Jun 02 '14 at 08:31
  • Oh, I see, you misunderstood what I was saying. I phrased it the way I did to avoid leading your answers, although it may be unlikely I would. It was just a precaution. – user3682802 Jun 02 '14 at 08:34
  • `val2` is declared as a `WORD`. Assuming this is for x86 (you haven't specified the CPU architecture), a word is 16 bits. So it's not a byte. Also, the value could be viewed as both signed and unsigned. Which way to choose to view it depends on the instructions you use. – Michael Jun 02 '14 at 08:34
  • x86, it's still unsigned, though...? – user3682802 Jun 02 '14 at 08:36
  • If I use increment, it assumes it's signed? – user3682802 Jun 02 '14 at 08:39
  • That doesn't really matter for the outcome of the addition. And the sign flag is set based on the most significant bit of the result. – Michael Jun 02 '14 at 08:41
  • This book says "the Sign Flag is set when the result of an artihmetic operation is negative." You can understand my confusion now. What good would setting the sign flag to the most significant bit be? – user3682802 Jun 02 '14 at 08:44
  • because in 2's complement all negative values are when highest bit is set. for example this is how 8bit looks like ... < -129,-1,0,+1,+127 > = < 80h,FFh,00h,01h,7Fh > – Spektre Jun 02 '14 at 08:57
  • @Jester thanks for putting a bounty on this to get it assigned to a worthy answer. rkbh got my upvote as I think his animated GIF is worth a thousand words. – Michael Petch Nov 17 '15 at 16:39

3 Answers3

23

Imagine it as a kind of analog clock. In a real clock the times "six fifty-five" (55) and "five to seven" (-5) are identical. It's just an issue of your definition, the clock itself doesn't know your definition and runs round and round and round... The same with the CPU. Look at the following "CPU-clock":

CPU-clock (Addition)

I've chosen a 4-bit-clock, but the principle is the same for every other group of bits (BYTE, WORD, DWORD etc.).

The carry flag will be set after the clock has jumped from 15 to 0. It is in this case a flag for unsigned overflow.

The overflow flag will be set after the clock has jumped from 7 to -8. It flags a signed overflow.

The sign flag flags a value which can be interpreted as a negative number.

The behavior of the flags is a little bit different, if you count downwards:

CPU-clock (Subtraction)

rkhb
  • 14,159
  • 7
  • 32
  • 60
1

Trying to summarize what was already discussed in most of the comments...

x86, as well as all other processor architectures I've seen so far, have no real notion of signed and unsigned numbers. It is your interpretation that determines whether the 16-bit value 8000h is +32768 (unsigned) or -32768 (signed).

There are no separate signed and unsigned instructions to add and subtract; again, you decide whether 7FFFh + 0001h is a valid (unsigned) addition, or an overflow (since 7FFFh is the maximum signed integer in 16-bit twos' complement).

To help you as a programmer, the arithmetic operations set flags for both interpretations. After the operation has completed, you test the appropriate flags. Rule of thumb:

  • for signed numbers, test the overflow and sign flag
  • for unsigned numbers, test the carry flag; it acts more or less as an 'unsigned overflow'

Examples:

  • 7FFFh + 1 overflows when signed (OF is set), not when unsigned (CF = 0); the result 8000h is negative when signed (SF = 1)
  • FFFFh + 1 overflows when unsigned (CF is set), not when signed (OF = 0); the result 0000h is not negative (SF = 0)
Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45
0

1.specify platform flags can be set differently on different platform

2.also what bit wide the used instructions are?

 8000h
+0001h
------
 8001h -> Carry=0,Sign16=1

 7FFFh
+0001h
------
 8000h -> Carry=0,Sign16=1
  • most CPU's does not handle numbers as signed instead use 2'os complement binary representation
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • sign is copy of the highest bit of the operation – Spektre Jun 02 '14 at 08:39
  • The second question asks for the overflow flag, not the carry flag. – Michael Jun 02 '14 at 08:40
  • Yea, sorry. It says OF = 1 still, though... You put carry in your answer. – user3682802 Jun 02 '14 at 08:41
  • @user3682802 x86 add Overflow is the same as Carry if my memory serves well http://x86.renejeschke.de/html/file_module_x86_id_5.html – Spektre Jun 02 '14 at 08:51
  • My confusion is not really the flags, those are simple concepts. My confusion is why a variable declared as a word (an unsigned 16-bit value) is being interpreted a signed complement. Can you help me there? – user3682802 Jun 02 '14 at 08:57
  • @user3682802 all numbers are handled as unsigned values inside ALU ... signed numbers are just differently printed/readed unsigned values by the program not by the CPU. (+/-,++,--) operations are the same. Diferencies starts with (*,/,%,<<,>>) and BCD code so for that you have separate instructions for signed and unsigned values (inside ALU) – Spektre Jun 02 '14 at 09:02
  • Awesome. I've read this chapter 4 times now and it never mentions that. ALU is the register used by inc? – user3682802 Jun 02 '14 at 09:03
  • 1
    _"add Overflow is the same as Carry if my memory serves well"_. Not really. Overflow occurs if you add two numbers with the same sign and get a result with a different sign. – Michael Jun 02 '14 at 09:06
  • @user3682802 ALU is Arithmetic & Logic Unit not register !!! it is a part of CPU that can do basic operations like +,-,++,--,<<,>> – Spektre Jun 02 '14 at 09:06
  • @Michael (+1)I think you are right (removed wrong assigment from answer) – Spektre Jun 02 '14 at 09:10
  • How would I get the ALU to perform an operation on a value that has its MSB equal to 1 when I wanted to be interpreted as unsigned then? – user3682802 Jun 02 '14 at 09:11
  • @user3682802 heh you just do it there is no difference between doing signed ADD: -1+-1 = -2 or unsigned ADD: FF+FF=(1)FE. The only difference is how you print the result FEh = 254 or = -2 – Spektre Jun 02 '14 at 09:16
  • @user3682802: You seem to be focusing on something that really doesn't matter. If you have the byte 0x80 and add 1 to it the result will be 0x81. The sign flag will be set because the most significant bit of the result is set. Whether you want to view the result (0x81) as 129 or -127 is up to you (by checking different flags). – Michael Jun 02 '14 at 09:19
  • I understand entirely... Thank you. – user3682802 Jun 02 '14 at 09:21