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
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:
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":
So finally, to address your homework question, let's see:
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