CHAPTER 24. 64-BIT VALUES IN 32-BIT ENVIRONMENT CHAPTER 24. 64-BIT VALUES IN 32-BIT ENVIRONMENT
push OFFSET $SG1436 ; '%I64d', 0aH, 00H
call _printf
add esp, 28
ret 0
_f_add_test ENDP
_f_sub PROC
mov eax, DWORD PTR _a$[esp-4]
sub eax, DWORD PTR _b$[esp-4]
mov edx, DWORD PTR _a$[esp]
sbb edx, DWORD PTR _b$[esp]
ret 0
_f_sub ENDP
We can see in thef_add_test()function that each 64-bit value is passed using two 32-bit values, high part first, then
low part.
Addition and subtraction occur in pairs as well.
In addition, the low 32-bit part are added first. If carry was occurred while adding, the CF flag is set. The following
ADCinstruction adds the high parts of the values, and also adds 1 ifCF= 1.
Subtraction also occurs in pairs. The firstSUBmay also turn on the CF flag, which is to be checked in the subsequent
SBBinstruction: if the carry flag is on, then 1 is also to be subtracted from the result.
It is easy to see how thef_add()function result is then passed toprintf().
Listing 24.6: GCC 4.8.1 -O1 -fno-inline
_f_add:
mov eax, DWORD PTR [esp+12]
mov edx, DWORD PTR [esp+16]
add eax, DWORD PTR [esp+4]
adc edx, DWORD PTR [esp+8]
ret
_f_add_test:
sub esp, 28
mov DWORD PTR [esp+8], 1972608889 ; 75939f79H
mov DWORD PTR [esp+12], 5461 ; 00001555H
mov DWORD PTR [esp], 1942892530 ; 73ce2ff_subH
mov DWORD PTR [esp+4], 2874 ; 00000b3aH
call _f_add
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp+8], edx
mov DWORD PTR [esp], OFFSET FLAT:LC0 ; "%lld\12\0"
call _printf
add esp, 28
ret
_f_sub:
mov eax, DWORD PTR [esp+4]
mov edx, DWORD PTR [esp+8]
sub eax, DWORD PTR [esp+12]
sbb edx, DWORD PTR [esp+16]
ret
GCC code is the same.
24.2.2 ARM.
Listing 24.7: Optimizing Keil 6/2013 (ARM mode)
f_add PROC
ADDS r0,r0,r2
ADC r1,r1,r3
BX lr
ENDP