Most modern compilers provide built-in support for 64-bit data types.
These data types are usually stored as two 32-bit integers in memory, and the
compiler generates special code when arithmetic operations are performed on
them. The following sections describe how the common arithmetic functions
are performed on such data types.
Addition
Sixty-four-bit integers are usually added by combining the ADDinstruction
with the ADC(add with carry) instruction. The ADCinstruction is very similar
to the standard ADD, with the difference that it also adds the value of the carry
flag (CF) to the result.
The lower 32 bits of both operands are added using the regular ADDinstruc-
tion, which sets or clears CF depending on whether the addition produced a
remainder. Then, the upper 32 bits are added using ADC, so that the result from
the previous addition is taken into account. Here is a quick sample:
mov esi, [Operand1_Low]
mov edi, [Operand1_High]
add eax, [Operand2_Low]
adc edx, [Operand2_High]
Notice in this example that the two 64-bit operands are stored in registers.
Because each register is 32 bits, each operand uses two registers. The first
operand uses ESIfor the low part and EDIfor the high part. The second
operand uses EAXfor the low-part and EDXfor the high part. The result ends
up in EDX:EAX.
Subtraction
The subtraction case is essentially identical to the addition, with CF being used
as a “borrow” to connect the low part and the high part. The instructions used
are SUBfor the low part (because it’s just a regular subtraction) and SBBfor the
high part, because SBBalso includes CF’s value in the operation.
mov eax, DWORD PTR [Operand1_Low]
sub eax, DWORD PTR [Operand2_Low]
mov edx, DWORD PTR [Operand1_High]
sbb edx, DWORD PTR [Operand2_High]
Multiplication
Multiplying 64-bit numbers is too long and complex an operation for the com-
piler to embed within the code. Instead, the compiler uses a predefined function
Understanding Compiled Arithmetic 529
22_574817 appb.qxd 3/16/05 8:45 PM Page 529