Notes about x86 CPU architecture and design.
This write up by Sivarama P. Dandamudi provides an excellent overview of x86 addressing:
The following example is based on this stackoverflow question and answer by Future Gadget and Peter Cordes:
; + offset (i.e., the result of math in brackets)
; |
; |-------------|
imul eax, DWORD PTR [esi+ebx*4-0x4]
; | | | |
; | | | + displacement (optional)
; | | |
; | | + scale (optional)
; | |
; | + index (here, "scaled index")
; |
; + base (optional)
;
; What actually happens here:
;
; 1. ebx * 4
; 2. esi + the result of operation 1
; 3. substract 4 from the result
; 4. go to the address (result) and get the value inside it.
x86 CPUs align call stack memory on a 16 byte boundary.
; if esp == 0x7fAABBCC, then esp == 0x7FAABBC0
and esp, 0xfffffff0
eax
(or rax
on 64-bit) is used to store the return value.