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</p>
The C code
a * 8;</p>
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)</p>
The C code
a * 6;</p>
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</p>
The C code
a % 8;</p>
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</p>
The C code
a / 8;</p>
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</p>
The C code
c / 6</p>
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</p>
The C code
c % 6</p>