Assembly Language for Beginners

(nextflipdebug2) #1

1.20. ARRAYS


Listing 1.255: Optimizing GCC 4.9 x64
movsx rdi, edi
lea rax, [rdi+rdi*4]
lea rax, month2[rax+rax]
ret

LEAis also used here for multiplication by 10.


Non-optimizing compilers do multiplication differently.


Listing 1.256: Non-optimizing GCC 4.9 x64

get_month2:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
movsx rdx, eax
; RDX = sign-extended input value
mov rax, rdx
; RAX = month
sal rax, 2
; RAX = month<<2 = month4
add rax, rdx
; RAX = RAX+RDX = month
4+month = month5
add rax, rax
; RAX = RAX
2 = month52 = month10
add rax, OFFSET FLAT:month2
; RAX = month
10 + pointer to the table
pop rbp
ret


Non-optimizing MSVC just usesIMULinstruction:


Listing 1.257: Non-optimizing MSVC 2013 x64

month$ = 8
get_month2 PROC
mov DWORD PTR [rsp+8], ecx
movsxd rax, DWORD PTR month$[rsp]
; RAX = sign-extended input value into 64-bit one
imul rax, rax, 10
; RAX = RAX10
lea rcx, OFFSET FLAT:month2
; RCX = pointer to the table
add rcx, rax
; RCX = RCX+RAX = pointer to the table+month
10
mov rax, rcx
; RAX = pointer to the table+month10
mov ecx, 1
; RCX = 1
imul rcx, rcx, 0
; RCX = 1
0 = 0
add rax, rcx
; RAX = pointer to the table+month10 + 0 = pointer to the table+month10
ret 0
get_month2 ENDP


But one thing is weird here: why add multiplication by zero and adding zero to the final result?


This looks like a compiler code generator quirk, which wasn’t caught by the compiler’s tests (the result-
ing code works correctly, after all). We intentionally consider such pieces of code so the reader would
understand, that sometimes one shouldn’t puzzle over such compiler artifacts.


32-bit ARM


Optimizing Keil for Thumb mode uses the multiplication instructionMULS:

Free download pdf