1

I understood the logic of the carry flag and the overflow flag. But, when I read this program (wrote in MASM 8086) , I got perplexed a bit.

The program intent is to tell if a quadratic equation has two distincts solutions, two equals solutions or no solutions at all.

.model small
.stack
.data
aa dw 2
bb dw 4
cc dw 2
sol_msg    db "There exist two real solutions", CR, NL
no_sol_msg db "No real solutions!            ", CR, NL
sol_coinc  db "The two solutions coincide!   ", CR, NL
.code
.startup
mov ax, bb
imul bb
jc overflow ; I decided to work at most with 16-bit numbers
push ax
mov ax, aa
imul cc
jc overflow
mov bx, 4
imul bx
jc overflow
pop bx
sub bx, ax
jo overflow
js mess2
jz mess3
lea si, sol_msg
jmp next
mess2: lea si, no_sol_msg
jmp next
mess3: lea si, sol_coinc
next: mov bx, LUNG_MSG
mov ah, 2
loop1: mov dl, [si]
INT 21h
inc si
dec bx
jnz loop1
jmp end1
overflow:
nop
end1: 
.exit
end

Now, my doubt is: why for the first three checks it has been tested the carry flag and for the last one the overflow flag?

Since in the last one, we do the subtraction between two signed numbers (as we think those), we have to check the overflow flag to see if there's an overflow (i.e. if the numbers goes beyond the interval[-2^15,2^15-1]). But for the first one, for example, we do (bb)^2 with imul.

So we think them as 16-bit signed numbers (so -2^15 <= bb <= 2^15-1 ) and, the multiplication set the CF/OF bit on if at least one sum (in the multiplication algorithm) get the CF/OF bit on.

But since we treat signed numbers, shouldn't we check the overflow flag ?

Also I noticed that, since 2^15-1=32767, if I set bb to 190 (190^2=36100) the CF=0; if bb equals 200 (200^2=40000) the CF=1.

Why is that? Could anybody explain me this in a detailed way, please?

P.S.: I'm using EMU8086.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
sl34x
  • 51
  • 2
  • 8

2 Answers2

3

If you have a look at the pseudo algorithm of IMUL in Intel's docs, you'll see

IF OperandSize = 16
THEN
  TMP_XP ← AX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
  DX:AX ← TMP_XP[31:0];
  SF ← TMP_XP[15];
  IF SignExtend(TMP_XP[15:0]) = TMP_XP
    THEN CF ← 0; OF ← 0;
    ELSE CF ← 1; OF ← 1;
  FI;
FI;

CF and OF either both set, or both cleared. So, you can check either flag after IMUL

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Alexander Zhak
  • 9,140
  • 4
  • 46
  • 72
  • @Alezander Zhak so, if `bb=190`, the 32-bit-product is `00000000000000001000110100000100` (i.e. 36100) and it's the same if I extend the sign to the first 16 bits. – sl34x Apr 26 '15 at 12:02
  • if, indeed, `bb=200`, the 32-bit-product is `00000000000000001001110001000000` (i.e. 40000) and it's also the same with the extended sign. Where am i wrong? – sl34x Apr 26 '15 at 12:04
  • `mov ax, bb / imul bb` will result the same flags for 190 and 200. or when do you check flags? – Alexander Zhak Apr 26 '15 at 12:20
  • I did `190*190=1000110100000100`. `SF=1` so the 32-bit-extension is `1111111111111111:1000110100000100` which is different from `0000000000000000:1000110100000100`. Is this the algorithm? – sl34x Apr 26 '15 at 12:25
  • I rechecked with EMU8086 and in both cases the flag is 1. So it's okay with what I wrote in the previous comment? – sl34x Apr 26 '15 at 12:27
  • Also: where did you find the algorythm? I'm looking for that of `MUL` too. – sl34x Apr 26 '15 at 12:55
  • 1
    Please look attentively: CF/OF are cleared **if sign extension takes place** . Everything is in IA 64 developer's manuals http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html – Alexander Zhak Apr 26 '15 at 13:02
1

For IMUL: The CF and OF flags are set when the signed integer value of the intermediate product differs from the sign extended operand-size-truncated product, otherwise the CF and OF flags are cleared. For the one operand form of the instruction, the CF and OF flags are set when significant bits are carried into the upper half of the result and cleared when the result fits exactly in the lower half of the result. I.e. these flags are almost equal here. For SUB: The SUB instruction performs integer subtraction. It evaluates the result for both signed and unsigned integer operands and sets the OF and CF flags to indicate an overflow in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result. OF is for signed. Check instruction set reference manual. It's still actual even for this old code. Yet please see x86 flags

Community
  • 1
  • 1
Zorgiev
  • 794
  • 1
  • 7
  • 19