Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi read overflow flag

If I do this

var
  a,b,c:cardinal;
begin
  a:=$80000000;
  b:=$80000000;
  c:=a+b;
end;

c will equal 0, since the addition overflowed. What's the best way to catch this overflowed boolean? (a+b<a) or (a+b<b)? a really nice way would be with inline assembler, but I'm not that prolific in assembler (though my guess would be it would envolve something like JO)

like image 669
Stijn Sanders Avatar asked Jun 20 '11 22:06

Stijn Sanders


Video Answer


1 Answers

In assembly the term Overflow usually refers to signed arithmetic and means that the sign of the sum is different from the signs of both operands; for unsigned arithmetic the term Carry is preferable.

You can implement addition with Overflow (Carry) check in pure pascal:

// signed add - returns True if no overflow produced
function SAdd(A, B: integer; out C: integer): Boolean;
begin
  C:= A + B;
  Result:= (A xor B < 0)   // operands have different signs
        or (C xor A >= 0); // sum has the same sign as operands
end;

// unsigned add - returns True if no carry produced
function UAdd(A, B: Cardinal; out C: Cardinal): Boolean;
begin
  C:= A + B;
  Result:= (C >= A);
end;

The same functions in assembly - optimized variant of Andreas' solution:

// Signed Add
function SAdd(A, B: Integer; out C: Integer): Boolean;
asm
        ADD   EAX,EDX
        MOV   [ECX],EAX
        SETNO AL
end;

// Unsigned Add
function UAdd(A, B: Cardinal; out C: Cardinal): Boolean;
asm
        ADD   EAX,EDX
        MOV   [ECX],EAX
        SETNC AL
end;
like image 163
kludg Avatar answered Sep 19 '22 17:09

kludg