CHAPTER 18. ARRAYS CHAPTER 18. ARRAYS
pop rbp
ret
Non-optimizing MSVC just usesIMULinstruction:
Listing 18.33: 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 resulting 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.
18.7.1 32-bit ARM.
Optimizing Keil for Thumb mode uses the multiplication instructionMULS:
Listing 18.34: Optimizing Keil 6/2013 (Thumb mode)
; R0 = month
MOVS r1,#0xa
; R1 = 10
MULS r0,r1,r0
; R0 = R1R0 = 10month
LDR r1,|L0.68|
; R1 = pointer to the table
ADDS r0,r0,r1
; R0 = R0+R1 = 10*month + pointer to the table
BX lr
Optimizing Keil for ARM mode uses add and shift operations:
Listing 18.35: Optimizing Keil 6/2013 (ARM mode)
; R0 = month
LDR r1,|L0.104|
; R1 = pointer to the table
ADD r0,r0,r0,LSL #2
; R0 = R0+R0<<2 = R0+R04 = month5
ADD r0,r1,r0,LSL #1
; R0 = R1+R0<<2 = pointer to the table + month52 = pointer to the table + month*10
BX lr