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 = month4+month = month5
add rax, rax
; RAX = RAX2 = month52 = month10
add rax, OFFSET FLAT:month2
; RAX = month10 + 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+month10
mov rax, rcx
; RAX = pointer to the table+month10
mov ecx, 1
; RCX = 1
imul rcx, rcx, 0
; RCX = 10 = 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: