上一篇我们提到,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,返回地址 |