上一篇我們提到,RE4B同時講解了x86/x64、ARM和MIPS三大架構,在繼續閱讀RE4B之前,我們先來快速了解一下這三大架構。當我們談架構的時候,其實是圍繞CPU在談CPU的指令集架構。和CPU相關的幾個重要概念在RE4B第一章就有介紹,分別是機器碼、匯編語言和寄存器。本文將簡單介紹一下各體系架構的寄存器,后續的文章我們再介紹常見的匯編指令。
這四大架構根據機器碼的字長可以簡單的分為兩類,x86/x64屬于CISC(復雜指令集),指令的機器碼字長是變長的;ARM和MIPS是RISC(精簡指令集),它們的機器碼字長是相同的。由于字長的限制,在匯編語言設計時需要做一些hack,因此你會發現ARM和MIPS有一些不同于x86/x64匯編語言的共性。
寄存器是匯編語言操作的重要對象,在學習某個架構的匯編語言之前,我們需要對寄存器有所了解。寄存器常常分為通用寄存器、專用寄存器(計數、堆棧、返回地址等)和狀態寄存器。
x86有8個通用寄存器而x64增加到了16個,如下表所示:
64bit | 32bit | 16bit | 8bit |
---|---|---|---|
rax | eax | ax | ah, al |
rbx | ebx | bx | bh, bl |
rcx | ecx | cx | ch, cl |
rdx | edx | dx | dh, dl |
rsi | esi | si | sih, sil |
rdi | edi | di | dih, dil |
rsp | esp | sp | sph, spl |
rbp | ebp | bp | bph, bpl |
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 |
x86和x64的狀態寄存器分別是flags和rflags。
ARM匯編中共有37個用戶可訪問的寄存器,分別為31個通用的32位寄存器和6個狀態寄存器。
name | user | system | supervisor | abort | undefined | interrupt | fast interrupt |
---|---|---|---|---|---|---|---|
r0 | r0 | r0 | r0 | r0 | r0 | r0 | r0 |
r1 | r1 | r1 | r1 | r1 | r1 | r1 | r1 |
r2 | r2 | r2 | r2 | r2 | r2 | r2 | r2 |
r3 | r3 | r3 | r3 | r3 | r3 | r3 | r3 |
r4 | r4 | r4 | r4 | r4 | r4 | r4 | r4 |
r5 | r5 | r5 | r5 | r5 | r5 | r5 | r5 |
r6 | r6 | r6 | r6 | r6 | r6 | r6 | r6 |
r7 | r7 | r7 | r7 | r7 | r7 | r7 | r7 |
r8 | r8 | r8 | r8 | r8 | r8 | r8 | r8_fiq |
r9(SB) | r9 | r9 | r9 | r9 | r9 | r9 | r9_fiq |
r10(SL) | r10 | r10 | r10 | r10 | r10 | r10 | r10_fiq |
r11(FP) | r11 | r11 | r11 | r11 | r11 | r11 | r11_fiq |
r12(IP) | r12 | r12 | r12 | r12 | r12 | r12 | r12_fiq |
r13(SP) | r13 | r13 | r13_svc | r13_abt | r13_und | r13_irq | r13_fiq |
r14(LR) | r14 | r14 | r14_svc | r14_abt | r14_und | r14_irq | r14_fiq |
r15(PC) | r15 | r15 | r15 | r15 | r15 | r15 | r15 |
CPSR | CPSR | CPSR | CPSR | CPSR | CPSR | CPSR | CPSR |
SPSR | / | / | SPSR_svc | SPSR_abt | SPSR_und | SPSR_irq | SPSR_fiq |
MIPS體系結構中一共有32個通用寄存器,在匯編語言中可以用$0~$31表示,也可以用寄存器名字表示,如下表所示:
register | name | usage |
---|---|---|
$0 | zero | 第0號寄存器,值始終為0 |
$1 | $at | 保留寄存器 |
$2~$3 | $v0~$v1 | values,保存表達式或函數返回結果 |
$4~$7 | $a0~$a3 | arguments,作為函數的前4個參數 |
$8~$15 | $t0~$t7 | temporaried,供匯編程序使用的臨時寄存器 |
$16~$23 | $s0~$s7 | saved values,子函數使用時需要先保存原寄存器的值 |
$24~$25 | $t8~$t9 | temporaried,供匯編程序使用的臨時寄存器,補充$t0~$t7 |
$26~$27 | $k0~$k1 | 保留,中斷處理函數使用 |
$28 | $gp | global pointer,全局指針 |
$29 | $sp | stack pointer,堆棧指針,指向堆棧的棧頂 |
$30 | $fp | frame pointer,保存棧指針 |
$31 | $ra | return address,返回地址 |