# How to use SHL/SAL, LEA and Add for arithmetic operations

I'm having problem computing the following arithmetic questions using SHL/SAL, LEA and ADD, and hoping someone can help explain or find the best ways to apply those:

• Multiply a variable by 24
• Multiply a variable by 1000
• Sounds a bit like homework/assignment. Feb 23 at 10:17

`SHL` and `SAL` are the same instruction, they do the same: Shift bits to the left.

Shifting bits to the left is equivalent to multiplying by two.

For example, if you have the number 3 in the register AX, it would look something like this:

``````mov ax, 3 ; ax = 3 = 0000 0000 0000 0011
sal ax, 1 ; ax = 6 = 0000 0000 0000 0110
``````

`LEA` allows you to perform a memory-addressing computation in the instruction, so you can use it to calculate an effective address (without accessing it).

For example:

``````mov rax, 0x100
mov rdi, 0x200
lea rax, [rax + rdi*2 + 0x10]
; rax = rax + rdi*2 + 0x10
; rax = 0x100 + 0x200*2 + 0x10
; rax = 0x100 + 0x400 + 0x10
; rax = 0x510
``````

However, not all operations are valid addressing modes, you should check Intel SDM Volume 1 "Basic Architecture": Multiply a variable by 24.

With shifts you can only multiply by powers of two, the same happens with `lea`, however, you know that `24 = 3*8`, so you could do add 3 times the variable, and then multiply it by `8`.

``````; rax = var
lea rax, [rax + rax*2] ; rax = 3*var
sal rax, 3             ; rax = 3*var*8
``````

For 1000 we could do something similar, we know that `1000` is `2*5*2*5*2*5`

``````lea rax, [rax + rax*4] ; rax = 5*var
lea rax, [rax + rax*4] ; rax = 5*5*var
lea rax, [rax + rax*4] ; rax = 5*5*5*var
sal rax, 3             ; rax = 8*125*var = 1000*var
``````

An alternative could be:

``````lea rdi, [rax + rax*2] ; rdi = 3*var
sal rax, 7             ; rax = var*128
sub rax, rdi           ; rax = var*128 - var*3 = var * 125
sal rax, 3             ; rax = var*125 * 8
``````