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
)
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With