Sections
Personal tools
You are here: Home people lamer Archive 2007 May

Entries For: May 2007

2007-05-29

Interesting Arithmetic Assembly Sequences

Microsoft Visual C Compiler generates some interesting assembly instructions for common operations such as multiplication with, taking remainder and quotient by constants, especially powers of 2.

All examples below use signed integers.

Multiplication with a power of 2

We all know shl is normally used to multiply a number with a power of 2. This sequence uses lea instruction instead.

The ASM code

mov   eax, DWORD PTR _a$[esp+52]  ; eax takes value of a
lea   ecx, DWORD PTR [eax*8]      ; ecx takes value of a * 8

The C code

a * 8;

Multiplication with a constant

The compiler will try to fit the multiplication with lea and add instructions.

The ASM code

mov   eax, DWORD PTR _a$[esp+28]  ; eax takes value of a
lea   ecx, DWORD PTR [eax+eax*2]  ; ecx = eax * 3
add   ecx, ecx                    ; ecx = ecx * 2 (or, eax * 6)

The C code

a * 6;

Taking quotient of a division by a power of 2

This sequence is interesting because there is a conditional jump jns instruction.

The ASM code

mov   edx, DWORD PTR _a$[esp+36]
and   edx, -2147483641                        ; 80000007H
jns   SHORT $LN3@main
dec   edx
or    edx, -8                                 ; fffffff8H
inc   edx
$LN3@main:
; here edx takes the value of the quotient

The C code

a % 8;

Taking remainder of a division by a power of 2

There is only one shift instruction sar in this sequence.

The ASM code

mov   eax, DWORD PTR _a$[esp+44]
cdq
and   edx, 7
add   eax, edx
sar   eax, 3
; here eax takes the value of the remainder

The C code

a / 8;

Taking remainder of a division by a constant

Notice that 2aaaaaabH is 2^32 / 6.

The ASM code

mov   ecx, DWORD PTR _c$[esp+20]
mov   eax, 715827883                          ; 2aaaaaabH
imul  ecx
mov   eax, edx
shr   eax, 31                                 ; 0000001fH
add   eax, edx

The C code

c / 6

Taking quotient of a division by a constant

First, take the remainder. Then substract the original value with the multiplication of remainder and constant.

The ASM code

mov   ecx, DWORD PTR _c$[esp+12]
mov   eax, 715827883                          ; 2aaaaaabH
imul  ecx
mov   eax, edx
shr   eax, 31                                 ; 0000001fH
add   eax, edx
lea   edx, DWORD PTR [eax+eax*2]
add   edx, edx
sub   ecx, edx

The C code

c % 6

Powered by Plone CMS, the Open Source Content Management System