0

I dont understood something. This the question:

mov  al,-128d
mov  ah,40d
add  al,ah ;result is out of 8 bit unsigned range?

why carry flag dont turn on? it's need to be 88, 88 don't in the range of 0-255!

why the number little d in the end and not with little h? its decimal number?

why -128 + 40 equals 168?

How is it possible?

Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • 1
    It helps if you know about [two's complement](https://en.wikipedia.org/wiki/Two's_complement), which is the way that x86 stores negative numbers. It also helps if you actually *know* Intel x86 assembly and its common notations! – Some programmer dude Aug 04 '17 at 14:07
  • ok! i will do it now, thanks a lot!*ped7g* ---- i start study that yesterday, so i know really know a lot about it. *some programmer dude* –  Aug 04 '17 at 14:13
  • Where does that 88 come from? – harold Aug 04 '17 at 14:41

1 Answers1

5

Yes, the small "d" after digits means "decimal", so mov al,-128d is same as mov al,-128 or mov al,-80h.

I don't understand that part of question with 88.

About add al,ah:

It will do al = al + ah. Both registers are 8 bit "wide", and their content is (binary) AL = 10000000, AH = 00101000. Result of such addition is in binary 10101000 = 168 in decimal, when interpreted as 8 bit unsigned value.

But when you try to interpret the same value as 8 bit signed value, it is equal to -88.

The ADD itself, or the registers AL/AH do not understand your interpretation, they don't care, the ADD will do simple bit addition, and the CF is set when the last addition of top bit did overflow, which it didn't in this case (if the AL is interpreted as unsigned 8 bit value, it is equal to +128, and 128 + 40 = 168 => didn't exceed 255 => carry flag = 0).

Actually the result is neither out of 8 bit unsigned or signed range, the result is correct value 168 or -88, depending on which way you interpret it (as unsigned or signed), it's the same value in the AL. How you read/interpret it depends on the following code.

To have some unsigned 8b arithmetic going out of range, you need the result to be over 255, i.e.

    mov  al,150  ; binary 1001 0110
    mov  ah,150
    add  al,ah   ; al = 44 (low 8 bits of value 300), CF=1 (like 9th bit for ADD)
    ; 300 is in binary 0000 0001 0010 1100 (needs at least 9 bits)
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • signed - like a real number add ****** unsigned - in binery world? –  Aug 04 '17 at 16:55
  • @Haham I'm not sure if I understand you... for me "real number" is floating point decimal. In any way, the registers are in the first place BITS (i.e. `eax` = 32 bits). You can interpret them any way you wish, the same value inside `eax` can be interpreted/used as `float`, or as 32b signed integer, or 32b unsigned integer, or as packed 4x 8b unsigned values, or just as some custom scheme of some bits as flags and some bits as values, and all that combined into total 32 bits. What you did with `mov al,-128` was you set up `AL` to `0b10000000`. Doing `mov al,128` has exactly same result. – Ped7g Aug 04 '17 at 18:18
  • @Haham you used it by `ADD al,ah`, which is "addition of two 8b integer values", both signed, and unsigned at the same time, as the signed values are done by "two's complement", which behaves like that. (`10101000` is both 168 and -88, depends if you read the 8th bit as sign, or as +128 value). Basically you do both signed and unsigned integral types math with the same instructions, and only the `CMP + Jcc` parts differ, as you use different flags after compare to work with "signed" values. – Ped7g Aug 04 '17 at 18:19
  • i understand now a lot more!!! but for flags number are sign or unsign? –  Aug 04 '17 at 20:14
  • @Haham Both. x86 has many flags. Consider this example: `mov al,128` `cmp al,255` the resulting flags are: C=1, Z=0, S=1, O=0 (main flags for common "compare"), P=1 (rarely useful, if you know what exactly it means), A=1 (almost never useful (for BCD math)). So "flag" jumps `JC, JNZ, JS, JNO` would jump, "unsigned" jumps `JB, JBE` (JB = JC), and "signed" jumps `JL, JLE` would jump, because in unsigned interpretation the `cmp` did "128 < 255", and in signed interpretation the `cmp` did "-128 < -1" and both happened at the same time, what you pick depends on which flags you use after. – Ped7g Aug 05 '17 at 07:01
  • @Haham or to make it maybe a bit more obvious example: `mov al,120` `cmp al,150` ... now `JB` would jump, because 120 < 150 (unsigned interpretation), but `JL` would not jump, because 120 > -106. So if you use "signed" jumps (JL, JG, JLE, JGE, ...) in your code, those values are "signed", even if you load `-1` into `AL` as `mov al,255`, it will work as `-1`. And vice versa, if you use "unsigned" jumps like (JA, JB, JAE, JBE, ...) in the code, the values are "unsigned", even if you do `mov al,-1`, it's `255` for unsigned math. See: https://stackoverflow.com/documentation/x86/5808/control-flow – Ped7g Aug 05 '17 at 07:10