flat assembler
Message board for the users of flat assembler.

Index > Main > [solved] Signed subtraction with overflow

Author
Thread Post new topic Reply to topic
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 03 Feb 2024, 20:21
I understand from Intel specs that SUB sets OF flag if there is an overflow in the signed subtraction. But in this snippet,
Code:
mov al, 128
sub al, 10
jno $    
the jump is executed because the OF is zero.
Shouldn't it be set? 128 is -128 in signed arithmetic, subtracting 10 should overflow.
Am I missing something?
Post 03 Feb 2024, 20:21
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 913
Location: Russia
macomics 03 Feb 2024, 21:24
Code:
mov al, 11000000b ; -64
sub al, 10100000b ; -32
; al = 10010000b ; -96
;      0 = of - There is no loan from the older bit
jno ...    

Code:
mov al, 10000000b ; -128
sub al, 00001010b ; 10
; al = 01110110b ; 118
;      1 = of - There is loan from the older bit
jno ...    


add:
Code:
mov al, 00000011b ; 3
sub al, 00001010b ; 10
; al = 11111001b ; -7
;      0 = of - There is no loan from the older bit (cf = 1)
jno ...    


Last edited by macomics on 03 Feb 2024, 22:27; edited 2 times in total
Post 03 Feb 2024, 21:24
View user's profile Send private message Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 03 Feb 2024, 22:22
macomics wrote:
Code:
mov al, 11000000b ; -64
sub al, 10100000b ; -32
; al = 10010000b ; -96
;      0 = of - There is no loan from the older rank
jno ...    

Code:
mov al, 10000000b ; -128
sub al, 00001010b ; 10
; al = 01110110b ; 118
;      1 = of - There is loan from the older rank
jno ...    
Sorry I don't understand. What do you mean? In the second example you are saying like me that the OF flag should be set, aren't you?
So, is this a processor bug?
Post 03 Feb 2024, 22:22
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 913
Location: Russia
macomics 03 Feb 2024, 22:24
No. OF indicates the status of the highest bit (7-bit).

Code:
jo label ; OF = 1
jno label ; OF = 0
jl label / jnge label ; SF <> OF
jge label / jnl label ; SF = OF
jle label / jng label ; ZF = 1 | SF <> OF
jg label / jnle label ; ZF = 0 & SF = OF    
This is an additional flag for the SF flag


Last edited by macomics on 03 Feb 2024, 22:32; edited 2 times in total
Post 03 Feb 2024, 22:24
View user's profile Send private message Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 03 Feb 2024, 22:28
macomics wrote:
No. OF indicates the status of the highest bit (7-bit).
???
The status of the seventh bit is in SF, not OF
Post 03 Feb 2024, 22:28
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 913
Location: Russia
macomics 03 Feb 2024, 22:33
pfranz wrote:
The status of the seventh bit is in SF, not OF
SF is equivalent to 7-bit, and OF is its loan status

Code:
 -128 | 10000000b (bit7 = 1)
+
 - 10 | 11110110b (bit7 = 1)
----------------
 -138 | 01110110b (bit7 = 0 and (1 + 1 = 10b) => OF = 1 - overflow)
SF = 0 and OF = 1 (-128 < 10)

  -64 | 11000000b (bit7 = 1)
+
  -32 | 11100000b (bit7 = 1)
-----------------
  -96 | 10100000b (bit7 = 1 and (1 + 1 + 1 = 11b) => OF = 0 - no overflow)
SF = 1 and OF = 0 (-64 < -32)    
Post 03 Feb 2024, 22:33
View user's profile Send private message Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 04 Feb 2024, 00:08
My example is your first example.
As you say, -128 -10 = -138 which goes beyond the signed numbers that can be represented with 8 bits.
For this reason, there is an overflow, thus OF =1, as you correctly write.
Thus you agree with me.

If OF =1, jno should NOT jump. But it does. Why?
Post 04 Feb 2024, 00:08
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 789
Location: Adelaide
sinsi 04 Feb 2024, 00:27
The "overflow flag" isn't the same as "a number overflowing the bits available", all it indicates is that the result is wrong.
Quote:
If the sum of two numbers with the sign bits on yields a result number with the sign bit off, the "overflow" flag is turned on.

In your example, sub al,10 is the same as add al,-10
A good explanation is here
Post 04 Feb 2024, 00:27
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20129
Location: In your JS exploiting you and your system
revolution 04 Feb 2024, 00:28
pfranz wrote:
If OF =1, jno should NOT jump. But it does. Why?
It doesn't.

For your code OF=1
The jump is not taken.
Code:
~ cat pfranz.asm
format elf executable

        mov     al, 128
        sub     al, 10
        jno     .skip
        int3
    .skip:
        mov     eax, 1
        int     0x80
~ fasm pfranz.asm 
flat assembler  version 1.73.31  (16384 kilobytes memory)
2 passes, 98 bytes.
~ ./pfranz 
Trace/breakpoint trap (core dumped)
~     
Post 04 Feb 2024, 00:28
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8344
Location: Kraków, Poland
Tomasz Grysztar 04 Feb 2024, 09:36
revolution wrote:
pfranz wrote:
If OF =1, jno should NOT jump. But it does. Why?
It doesn't.

For your code OF=1
The jump is not taken.
Yes, this entire thread could have been resolved immediately.
sinsi wrote:
The "overflow flag" isn't the same as "a number overflowing the bits available", all it indicates is that the result is wrong.
Quote:
If the sum of two numbers with the sign bits on yields a result number with the sign bit off, the "overflow" flag is turned on.

In your example, sub al,10 is the same as add al,-10
A good explanation is here
There is also a generalized explanation I made in a video about 2-adic numbers for x86 programmers. And a more basic explanation in my tutorial series.

In short, OF is a flag telling whether the true sign of the result differs from the highest bit of the value put into the destination.

In other words OF = SF xor TS, where TS is the true sign of the result.

From this also follows that TS = OF xor SF, it is therefore easy to recover the true sign from the available flags (and it is how conditional instructions like JL and JG do it).
Post 04 Feb 2024, 09:36
View user's profile Send private message Visit poster's website Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 04 Feb 2024, 19:43
revolution wrote:
pfranz wrote:
If OF =1, jno should NOT jump. But it does. Why?
It doesn't.
You are correct. My bad.
The problem was somewhere else: I had to simplify the code so I left out the real culprit,

shl al, 3

before the jno. According to Intel specs, shl with a count >1 leaves OF UNCHANGED. Same shl in AMD specs leaves OF UNDEFINED (which means it MAY change).
And actually in my code OF changed to 0 when executed on AMD and VIA cpus (for which I started this thread), but did not on an Intel cpu.

Thanks for your help.
Post 04 Feb 2024, 19:43
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20129
Location: In your JS exploiting you and your system
revolution 05 Feb 2024, 05:03
AMD and Intel are consistent with the OF flag descriptions.
AMD wrote:
For 1-bit shifts, the instruction sets the OF flag to the exclusive OR of the CF bit (after the shift) and the most significant bit of the result. When the shift count is greater than 1, the OF flag is undefined.
Intel wrote:
The OF flag is affected only for 1-bit shifts (see “Description” above); otherwise, it is undefined.
Post 05 Feb 2024, 05:03
View user's profile Send private message Visit poster's website Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 05 Feb 2024, 19:32
revolution wrote:
AMD and Intel are consistent with the OF flag descriptions.
AMD wrote:
For 1-bit shifts, the instruction sets the OF flag to the exclusive OR of the CF bit (after the shift) and the most significant bit of the result. When the shift count is greater than 1, the OF flag is undefined.
Intel wrote:
The OF flag is affected only for 1-bit shifts (see “Description” above); otherwise, it is undefined.
I see now that phrase under the "Flags affected" section at page 4-595.
I had read only Intel Volume 2B-594 (page 1814 in the combined set of volumes 1-4 named 325462-sdm-vol-1-2abcd-3abcd-4.pdf):

The OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the
result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is
set to 1. For the SAR instruction, the OF flag is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set
to the most-significant bit of the original operand.

This misled me.
Post 05 Feb 2024, 19:32
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.