Practical exercises
Flags
01001011 -> 75
+01100100 -> 100
=10101111 -> -81 (overflow)
Flags:
Z (zero): 0
C (carry): 0
OV (overflow): 1
P (parity): 1
mov eax, [ebx + 32] - register indirect with displacement
[myVar + esi] is the same as mov eax, [esi + myVar]
[myVar + esi] can be called absolute indexed
[myVar + esi * 1] will be absolute with displacement
[myVar] - direct (absolute)
[vec + edx * 8] can be absolute indexed
vector of 8 byte elements (64-bit float, 64-bit, 8-byte struct)
add eax, [vec + edx * 8]
we could write [vec + edx * 8 + 2]. The value in [] is changes into a constant.
Access of vector of 8-byte elements, accessing a member of the struct at the offset of 2.
mov ax, [vec + edx * 8 + 2] ensures that the output is 16-bit. Can be uint16_t or int16_t
movzx eax, word[vec + edx * 8 + 2] - uint16_t (in x86)
movsx eax, word[vec + edx * 8 + 2] - int16_t (in x86)
movzx - move unsigned extended
movsx - move signed extended
[word] before the address, sets the side of the output. For x86:
word -> 16bit
for x64:
word -> 32bit
movsx eax, byte[ebp + edx * 8 + 2] - is incorrect
ebp accesses the stack pointer
every time, the first available passed variable is at [ebp + 8]
in our example, if edx = 0, then we'll be accessing [ebp + 2] which is incorrect
movsx eax, byte[ebp + edx * 8 - 100] - correct
local variable of a function (vector of 8-byte elements)
it must be a vector, as we're accessing something of a size<=8
names of addressing modes
investigation of a instruction -> what we know about the accessed object, what does the instruction do, etc