Intro to x86-64
x86 Control Flow
Memory & Word Size
B, W, L, Q
- Big-Endian: MS byte is put at the starting address.
-
Little-Endian: LS byte is put at the starting address.
$indicates the constant.- If hex without
$, it’s address
mov
Destination
- register
- Only when destination is register and it’s
movl, the rest of bytes are cleared to zero.
- Only when destination is register and it’s
- memory location
- Can’t move memory address to memory address
Zero / Sign Extension
- Can’t move memory address to memory address
- Destination should be register
movzxy: zero-extend- No
movzlq!!!
- No
movsxy: sign-extendcltqis equivalent tomovslq
Legal move combinations:
Imm -> RegImm -> MemReg -> RegReg -> MemMem -> Reg
Whenever there’s 4 bytes(l) operation, clear 4 bytes out!!!
Arithmetic Instructions
- Both operands cannot be memory
mul
- Unsigned:
mul[l,q] src - Signed:
imul[l,q] src - Long:
%edx:%eax = %eax * src (mull) - Quad:
%rdx:%rax = %rax * src (mulq)
div
- Unsigned:
div[l,q] src - Signed:
idiv[l,q] src - Divisor:
src, Quotient:%eax (%rax), Remainder:%edx (%rdx) - Long:
%eax = %edx:%eax / src (divl)%edx = %edx % src - Quad:
%rax = %rdx:%rax / src (divq)%rdx = %rdx:%rax % src
Translation to Assembly
4 steps to translate C to assembly
- Setup a pointer in a register
- Load data from memory to a register (mov)
- Process data (add, sun, and, or, shift, etc.)
- Store data back to memory (mov)
Inputs & Output:
rdi, rsi, rdx, rcx, r8, r9- Additional: pass on stack
- Output:
rax
Condition Codes (Flags)
SF: sign flag (copy MSB)ZF: zero flagOF: 2’s complement overflow flagCF: Unsigned overflow- When
test, OF and CF always set to 0. movandlealeave the condition codes unaffected.and, or, xorupdate only SF and ZF and *clear OF and CF to 0**notdoes not affect the condition codes
Shifts and Condition Codes
All shift instructions
- Set
SFandZF CF: last bit shifted outOF: undef for shifts of more than 1 bit- Left shift by 1-bit
OF: 1 if MSB changed
- Right shift by 1-bit
- Logical:
OF: original MSB of the input value - Arithmetic:
OFis always set to 0
- Logical:
- Left shift by 1-bit
Conditional Jump Instructions
jejumps ifZFjgejumps if~(SF^OF)-
jsjumps ifSF - Conditional moves are more pipelining friendly
System Stack
- Tip of stack is accessed and maintained using
%rsp(stack pointer) register %rsppoints at top occupied location of the stackpushq %regis equivalent tosubq $8, %rspmovq %rax, (%rsp)popq %regis equivalent tomovq (%rsp), %rdxaddq $8, %rsppushwandpopware also available.- If address is saved in register -> can’t use it
Caller & Callee-Saved Convention
- Callee-saved: preserved
- Callee must ensure the value is not modified
- Push values before overwriting them
- Restore before returning
%rbp, %rbx, %r12-r15, %rsp*
- Caller-saved: overwritten freely
- Caller must save the value if it wants to preserve it across a function call
- Push if the register value is needed after the function call
- Callee can freely overwrite
- Caller will restore upon return
all other registers