I was trying to understand how Address Computation Instruction works, especially with `leaq`

command. Then I get confused when I see examples using `leaq`

to do arithmetic computation. For example, the following C code,

```
long m12(long x) {
return x*12;
}
```

In assembly,

```
leaq (%rdi, %rdi, 2), %rax
salq $2, $rax
```

If my understanding is right, leaq should move whatever address `(%rdi, %rdi, 2)`

, which should be `2*%rdi+%rdi`

, evaluate to into `%rax`

. What I get confused is since value x is stored in `%rdi`

, which is just memory address, why does times %rdi by 3 then left shift this **memory address** by 2 is equal to x times 12? Isn't that when we times `%rdi`

by 3, we jump to another memory address which does not hold value x?

`leaq`

doesn'thaveto operate on memory addresses, and itcomputesan address, it doesn't actuallyreadfrom the result, so until a`mov`

or the like tries to use it, it's just an esoteric way to add one number, plus 1, 2, 4 or 8 times another number (or the same number in this case). It's frequently "abused"^{†}for mathematical purposes, as you see.`2*%rdi+%rdi`

is just`3 * %rdi`

, so it's computing`x * 3`

without involving the multiplier unit on the CPU.Similarly, left shifting, for integers, doubles the value for every bit shifted (every zero added to the right), thanks to the way binary numbers work (the same way in decimal numbers, adding zeroes on the right multiplies by 10).

So this is abusing the

`leaq`

instruction to accomplish multiplication by 3, then shifting the result to achieve a further multiplication by 4, for a final result of multiplying by 12 without ever actually using a multiply instruction (which it presumably believes would run more slowly, and for all I know it could be right; second-guessing the compiler is usually a losing game).^{†}: To be clear, it's not abuse in the sense ofmisuse, just using it in a way that doesn't clearly align with the implied purpose you'd expect from its name. It's 100% okay to use it this way.