Register Names
64-bit register | 32-bit sub-register | 16-bit sub-register | 8-bit sub-register |
---|---|---|---|
%rax | %eax | %ax | %al |
%rbx | %ebx | %bx | %bl |
%rcx | %ecx | %cx | %cl |
%rdx | %edx | %dx | %dl |
%rsi | %esi | %si | %sil |
%rdi | %edi | %di | %dil |
%rbp | %ebp | %bp | %bpl |
%rsp | %esp | %sp | %spl |
%r8 | %r8d | %r8w | %r8b |
%r9 | %r9d | %r9w | %r9b |
%r10 | %r10d | %r10w | %r10b |
%r11 | %r11d | %r11w | %r11b |
%r12 | %r12d | %r12w | %r12b |
%r13 | %r13d | %r13w | %r13b |
%r14 | %r14d | %r14w | %r14b |
%r15 | %r15d | %r15w | %r15b |
architecture: byte order
references to memory
- -16(%rsp)
- 8(%rbp)
- 127(%rip)
relative addressing
syntax: disp(base,index,scale) -> base + index*scale +disp
eg: -3(%rbp,%rdi,8)
;typically used to access %rbp[%rdi] where each array element is 8 bytes long and you’re
;accessing at -3 bytes from it
addressing modes
;immediate:
mov $10, %eax
;register to register
mov %r8l, %al
;indirect
mov 1234(%rcx,%rax,8), %r8w
;it sometime is necessary to add a size postfix to instructions: movb, movw, movl, movq (b = byte, w = word, l = long, q = quadword)
;rip-relative:
movb 12(%rip), %al
a simple example
sum numbers 1 to 10 in register %eax
xor %eax, %eax # zero %eax – why not “mov $0, %eax” ?
mov $10, %ecx # set the loop index
lab:
add %ecx, %eax # %eax += %ecx
loop lab # dec %ecx, jump to lab if not zero
common instruction
MOV
movl $1, 0x604892 #direct (address is constant value)
movl $1, (%rax) #indirect (address is in register %rax)
movl $1, -24(%rbp) #address = base(%rbp) + displacement(-24)
movl $1, 8(%rsp,%rdi,4) #address = %rsp + 8 + %rdi*4
MOV V LEA
mov d(b,i,s), %rax is like rax = *(b+s*i+d)
lea d(b,i,s), %rax is like rax = (b+s*i+d)
CMOV
**CMOVcc instructions can replace two instructions in situations like **
"if ecx == 5 then eax = ebx”
cmp $5, %ecx
jnz continue
mov %ebx, %eax
continue:
;it equals to
cmp $5, %ecx
cmovz %ebx, %eax
push and pop
push <src> is like dec %rsp; mov <src>,(%rsp)
pop <dst> is like mov (%rsp),<dst>; inc %rsp
compile and link the files
testmax3.c
#include <stdio.h>
#include <inttypes.h>
int64_t maxofthree(int64_t, int64_t, int64_t);
int main() {
printf("%ld\n", maxofthree(1, -4, -7));
printf("%ld\n", maxofthree(2, -6, 1));
printf("%ld\n", maxofthree(2, 3, 1));
printf("%ld\n", maxofthree(-2, 4, 3));
printf("%ld\n", maxofthree(2, -6, 5));
printf("%ld\n", maxofthree(2, 4, 6));
return 0;
}
max3.s
.globl _maxofthree
.text
_maxofthree:
mov %rdi, %rax # result (rax) initially holds x
cmp %rsi, %rax # is x less than y?
cmovl %rsi, %rax # if so, set result to y
cmp %rdx, %rax # is max(x,y) less than z?
cmovl %rdx, %rax # if so, set result to z
ret
complie and link
clang -o result testmax3.c max3.s
then execute the result file
calling conventions
Register | Convention |
---|---|
%rip | Instruction pointer |
%rsp | Stack pointer |
%rax | Return value |
%rdi | 1st argument |
%rsi | 2nd argument |
%rdx | 3rd argument |
%rcx | 4th argument |
%r8 | 5th argument |
%r9 | 6th argument |
%r10,%r11 | Callee-owned |
%rbx,%rbp,%r12-%15 | Caller-owned |