ARM64 汇编语言

0x00. 前言

前面已经介绍过ARM32汇编语言,但是从ARMv8-A开始出现了64位的ARM指令集,因此有必要学习一下64位的ARM指令集。虽然ARM官方将64位的ARM指令集叫做Aarch64,但为了和前面ARM32对比,暂且叫64位的ARM指令集为ARM64。ARM32和ARM64属于两套不同的指令集,在此仅介绍ARM64指令集中的一些改变。

0x01. ARM64汇编中寄存器

ARM64微处理器中,程序员可以使用31个64位的通用寄存器x0x30,堆栈指针寄存器sp,指令指针寄存器pc。也可以只使用这些通用寄存器中的低32位,即w0w30,wsp。ARM遵循ATPCS规则,ARM64汇编语言函数前8个参数使用x0-x7寄存器(或w0-w7寄存器)传递,多于8个的参数均通过堆栈传递,并且返回值通过x0寄存器(或w0寄存器)返回。在使用软中断进行系统调时,系统调用号通过x8寄存器传递,用svc指令产生软中断,实现从用户模式到管理模式的切换。例如:

1
2
3
mov x0, 123 // exit code
mov x8, 93 // sys_exit() is at index 93 in kernel functions table
svc #0 // generate kernel call sys_exit(123);

0x02. AMR64汇编语言

ARM64汇编指令集所有指令的长度固定,每条指令是4字节(32位宽度),并且没有Thumb指令集。

  1. 访存指令
    ARM32中的LDM、STM、PUSH、POP指令,在ARM64中并不存在。取而代之的是LDP、STP指令,如一般在函数开头用来代替PUSH.
    例如,用IDA Pro逆向的某个ARM64 SO库函数的开头和结尾:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    STP      X24, X23, [SP,#var_40]!
    STP X22, X21, [SP,#0x40+var_30]
    STP X20, X19, [SP,#0x40+var_20]
    STP X29, X30, [SP,#0x40+var_10]
    ADD X29, SP, #0x40+var_10
    ....
    SUB SP, X29, #0x30
    LDP X29, X30, [SP,#0x150+var_120]
    LDP X20, X19, [SP,#0x150+var_130]
    LDP X22, X21, [SP,#0x150+var_140]
    LDP X24, X23, [SP+0x150+var_150],#0x40
    RET
  2. 跳转指令
    跳转和链接指令,将PC保存到链接寄存器(BL和BLR)。

  3. ARM64指令
    ARM32指令集在涉及程序计数器(PC)计算时,由于多流水线的原因,需要加上4或者8的偏移。而ARM64指令集在涉及程序计数器(PC)计算时,不需要加上偏移。能够修改PC的唯一的方式,使用隐式的控制流指令(条件跳转,无条件跳转,异常生成,异常返回)。

PS: 由于时间关系,没有深入学习ARM64汇编指令集。以后有时间,继续补充本文,2017.03.24。

0x03. 参考文献

1. Wiki ARM Architecture
2. Aarch64 Register and Instruction Quick Start
3. ARMarch64汇编学习笔记
4. ARM The Architecture for the Digital World