aboutsummaryrefslogblamecommitdiffhomepage
path: root/src/arch/x86_64.md
blob: 5498569e8fecfd39a1184b3cd109df7b247ab370 (plain) (tree)
1
2
3
4
5
6
7
8
        





                                                      
 














                                                          
                                    











































                                                             
         





                                                       
                             


















                                  
             
     

                                                                          






































                                                                               
         







                                                                  
         

     












                                                 




















                                                                 
                                                        















                                                             
             
                              


                                                                 



                                                          

                                            
                                                         






                                                                                      


                                                                                                                                                                                      
                                                  
                                                                                    
                                                                             
# x86_64
keywords: x86_64, x86, abi

- 64bit synonyms: `x86_64`, `x64`, `amd64`, `intel 64`
- 32bit synonyms: `x86`, `ia32`, `i386`
- ISA type: `CISC`
- Endianness: `little`


## Registers
### General purpose register
```markdown
bytes
[7:0]      [3:0]   [1:0]   [1]   [0]     desc
----------------------------------------------------------
rax        eax     ax      ah    al      accumulator
rbx        ebx     bx      bh    bl      base register
rcx        ecx     cx      ch    cl      counter
rdx        edx     dx      dh    dl      data register
rsi        esi     si      -     sil     source index
rdi        edi     di      -     dil     destination index
rbp        ebp     bp      -     bpl     base pointer
rsp        esp     sp      -     spl     stack pointer
r8-15      rNd     rNw     -     rNb
```

### Special register
```markdown
bytes
[7:0]      [3:0]     [1:0]      desc
---------------------------------------------------
rflags     eflags    flags      flags register
rip        eip       ip         instruction pointer
```

### FLAGS register

```markdown
rflags
bits  desc
-----------------------------
[11]  OF overflow flag
[10]  DF direction flag
 [7]  SF sign flag
 [6]  ZF zero flag
 [4]  AF auxiliary carry flag
 [2]  PF parity flag
 [0]  CF carry flag
```

## Addressing
```asm
movw [rax], rbx         // save val in rbx at [rax]
movw [imm], rbx         // save val in rbx at [imm]
movw rax, [rbx+4*rcx]   // load val at [rbx+4*rcx] into rax
```

`rip` relative addressing:
```asm
lea rax, [rip+.my_str]       // load addr of .my_str into rax
...
.my_str:
.asciz "Foo"
```

## Size directives
Explicitly specify size of the operation.

```x86asm
mov  byte ptr [rax], 0xff    // save 1 byte(s) at [rax]
mov  word ptr [rax], 0xff    // save 2 byte(s) at [rax]
mov dword ptr [rax], 0xff    // save 4 byte(s) at [rax]
mov qword ptr [rax], 0xff    // save 8 byte(s) at [rax]
```

## [SysV x86_64 ABI][sysvabi]

### Passing arguments to functions
- Integer/Pointer arguments
  ```markdown
  reg     arg
  -----------
  rdi       1
  rsi       2
  rdx       3
  rcx       4
  r8        5
  r9        6
  ```
- Floating point arguments
  ```markdown
  reg     arg
  -----------
  xmm0      1
    ..     ..
  xmm7      8
  ```
- Additional arguments are passed on the stack. Arguments are pushed
  right-to-left (RTL), meaning next arguments are closer to current `rsp`.

### Return values from functions
- Integer/Pointer return values
  ```markdown
  reg          size
  -----------------
  rax        64 bit
  rax+rdx   128 bit
  ```
- Floating point return values:
  ```markdown
  reg            size
  -------------------
  xmm0         64 bit
  xmm0+xmm1   128 bit
  ```

### Caller saved registers
Caller must save these registers if they should be preserved across function
calls.
- `rax`
- `rcx`
- `rdx`
- `rsi`
- `rdi`
- `rsp`
- `r8` - `r11`

### Callee saved registers
Caller can expect these registers to be preserved across function calls. Callee
must must save these registers in case they are used.
- `rbx`
- `rbp`
- `r12``r15`

### Stack
- grows downwards
- frames aligned on 16 byte boundary
  ```text
  Hi ADDR
   |                +------------+
   |                | prev frame |
   |                +------------+ <--- 16 byte aligned (X & ~0xf)
   |       [rbp+8]  | saved RIP  |
   |       [rbp]    | saved RBP  |
   |       [rbp-8]  | func stack |
   |                | ...        |
   v                +------------+
  Lo ADDR
  ```

### Function prologue & epilogue
- prologue
  ```x86asm
  push rbp        // save caller base pointer
  mov rbp, rsp    // save caller stack pointer
  ```
- epilogue
  ```x86asm
  mov rsp, rbp    // restore caller stack pointer
  pop rbp         // restore caller base pointer
  ```
  > Equivalent to `leave` instruction.

## ASM skeleton
Small assembler skeleton, ready to use with following properties:
- use raw Linux syscalls (`man 2 syscall` for ABI)
- no `C runtime (crt)`
- gnu assembler [`gas`][gas_doc]
- intel syntax
```x86asm
# file: greet.s

    .intel_syntax noprefix

    .section .text, "ax", @progbits
    .global _start
_start:
    mov rdi, 1                      # fd
    lea rsi, [rip + greeting]       # buf
    mov rdx, [rip + greeting_len]   # count
    mov rax, 1                      # write(2) syscall nr
    syscall

    mov rdi, 0                      # exit code
    mov rax, 60                     # exit(2) syscall nr
    syscall

    .section .rdonly, "a", @progbits
greeting:
    .asciz "Hi ASM-World!\n"
greeting_len:
    .int .-greeting
```
> Syscall numbers are defined in `/usr/include/asm/unistd.h`.

To compile and run:
```bash
> gcc -o greet greet.s -nostartfiles -nostdlib && ./greet
Hi ASM-World!
```

## References
- [SystemV AMD64 ABI][sysvabi]
- [AMD64 Vol1: Application Programming][amd64_vol1]
- [AMD64 Vol2: System Programming][amd64_vol2]
- [AMD64 Vol3: General-Purpose & System Instructions][amd64_vol3]
- [X86_64 Cheat-Sheet][x86_64_cheatsheet]
- [Intel 64 Vol1: Basic Architecture][intel64_vol1]
- [Intel 64 Vol2: Instruction Set Reference][intel64_vol2]
- [Intel 64 Vol3: System Programming Guide][intel64_vol3]
- [GNU Assembler][gas_doc]
- [GNU Assembler Directives][gas_directives]
- [GNU Assembler `x86_64` dependent features][gas_x86_64]


[sysvabi]: https://www.uclibc.org/docs/psABI-x86_64.pdf
[amd64_vol1]: https://www.amd.com/system/files/TechDocs/24592.pdf
[amd64_vol2]: https://www.amd.com/system/files/TechDocs/24593.pdf
[amd64_vol3]: https://www.amd.com/system/files/TechDocs/24594.pdf
[x86_64_cheatsheet]: https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf
[intel64_vol1]: https://software.intel.com/content/www/us/en/develop/download/intel-64-and-ia-32-architectures-software-developers-manual-volume-1-basic-architecture.html
[intel64_vol2]: https://software.intel.com/content/www/us/en/develop/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-2a-2b-2c-and-2d-instruction-set-reference-a-z.html
[intel64_vol3]: https://software.intel.com/content/www/us/en/develop/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-3a-3b-3c-and-3d-system-programming-guide.html
[gas_doc]: https://sourceware.org/binutils/docs/as
[gas_directives]: https://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops
[gas_x86_64]: https://sourceware.org/binutils/docs/as/i386_002dDependent.html