ARM指令集

ARM指令集基础知识

前段时间学习了下ARM指令集的基础只是,方便往后记录学习

ARM简介

在CTF比赛中,大部分的题目都是由x86,x86_64的程序。这一类的程序属于intel处理器所支持的,但是在我们现实中比如安卓,网络设备,智能家电等等使用ARM架构的处理器要比intel多很多。

Intel和arm的主要区别的是指令集:

*cisc复杂指令集

*risc精简指令集

精简指令集会通过减少每条指令时钟周期来缩短执行时间,以达到更快的执行命令,但是因为命令比较少,所以实现功能的时候,会比intel长

其次,在x86架构中大多数指令都是可以直接对内存数据进行操作,在ARM上,必须将内存中的数据移动到寄存器上面才可以进行操作。

Intel和arm更多的差别是:

  • 在arm中,多数指令用于条件执行
  • 在intel x86和x86_64一系列处理器用little-endian格式
  • 在v3处理器之前arm的体系结构还是little-endian字节序,从此之后arm体系结构便改为了BI-endian字节序,并允许可切换字节序。

ARM数据类型和寄存器

字节序:

有两个查看字节的基本方法:小端和大端,在ARM体系中具有允许可切换字节序的设置。

寄存器:

  • 寄存器的数量取决于arm的版本

32位

  • 在ARM32位中有30个寄存器,前16个寄存器可以在用户模式下进行访问,其他寄存器则需要在特权软件执行中使用,也就是R0-R15寄存器可以在任何权限模式下使用,这16个寄存器可以分为俩组:通用寄存器(r0-r11)和专用寄存器(r12-r15)
  • R0-R12:可以在常规操作时间内用于存储临时值
  • R0:在算术操作时间内被叫做累加器,用于存储之前调用的函数结果,个人感觉象rax
  • R7:用于存储系统的调用号(重点)
  • R11:用来帮助我们跟踪用作帧指针的堆栈边界
  • 在ARM的系统调用前四个参数存储在R0-R3!!!!!!(重点)
  • R13:sp(堆栈指针)指向堆栈顶部
  • R14:LR(链接寄存器),当我们进行功能调用的时候,链接寄存器会将使用的一个内存地址进行更新,该内存地址引用了从其开始该功能的下一条指令。这样做可以使得程序回到“父”函数,改函数在子函数完成后启动子函数系统调用
  • R15:PC(程序计数器)PC自动增加执行指令的大小,在ARM状态下,此大小始终会是4个字节,在thumb模式下,此大小始终为2个字节,当实行转移指令时,PC会保留目标地址,在执行期间,PC在ARM状态下+8(在thumb模式下+4),这和X86的状态下不同,X86的PC始终指向下一条命令

电脑萤幕画面

描述已自动生成

表格

描述已自动生成

当参数少于4个的时候,子程序间会通过寄存器R0-R3来传递参数,当多于4个的时候,会通过栈来传递参数。

在子程序中,使用R4-R11会保存局部变量,若是我们使用需要入栈保存,子程序返回前需要恢复这些寄存器,R12是临时寄存器不需要恢复。

子程序返回32位的整数时,使用r0返回,当返回64的整数的时候,会使用r0来返回低位,r1返回高位。

64位

  • X0~x7:用于传递子程序的参数和结果,使用时不需要保存,多余的参数利用堆栈传递,64位返回结果采用x0表示,128位返回结果采用x1:x0
  • X8:用于保存子程序返回地址,尽量不要用
  • X9~X15:临时寄存器,用的时候不要保存
  • X16~x17:子程序内部调用的寄存器,使用的时候不需要保存,尽量不要用
  • X18:平台寄存器,他的使用跟平台相关,尽量不要用
  • X19~X28:临时寄存器,使用的时候必须保存。
  • X29:帧指针寄存器,用于连接栈帧,使用时需要保存
  • X30:LR(链接寄存器)
  • X31:SP(堆栈指针寄存器)或ZXR(零寄存器)

子程序调用必须要保存的寄存器X19~X29和sp(X31),不要保存的寄存器就是X0~X7和X9~X15

32位和64位寄存器的差异

  • 栈arm32位下,前4个参数都是通过r0-r3传递,第四个参数就需要通过sp来访问第五个参数就需要通过sp+4访问,第n个参数需要通过sp+4*(n-4)来访问。
  • Arm64位下,前8个餐宿是通过x0~x7传递,第8个参数需要通过sp访问,第9个参数需要通过sp+8访问,第n个参数需要通过sp+8*(n-8)来访问.
  • ARM指令在32和64位下并非不是完全一样的,但是大部分的指令都是通用的,特别的就是“ MOV r2,r1,lsl #2”,只有在ARM32位下支持,他就等于ARM64位下的“ lsl r2,r1,#2”一样
  • 还有一些ARM32位存在的指令在ARM64位下是不存在的比如:vswl指令,条件执行指令subgt,addle等。。。

ARM指令集

Arm处理器中有两个可以运行的主要状态,此处不包括lazelle:ARM和thumb,这俩个状态的主要区别时指令集,其中arm的指令始终是32位,tmumb下的指令始终是16位(也可以是32位),现在,ARM加入了增强的tmumb指令集(tmumbv2)

Thumb和ARM一样也有不同的版本

  • Thumb-1 (16位指令): 在ARMv6和更早的体系结构中使用
  • Thumb-2(16位和32位指令): 通过添加更多指令并使它们的宽度为16位或32位(ARMv6T2,ARMv7) 来扩展Thumb-1
  • ThumbEE:包括一些针对动态生成的代码的更改和添加

ARM和Thumb之间的区别

  • 条件执行: ARM状态下的所有指令均支持条件执行。某些ARM处理器版本允许使用“it”指令在Thumb中有条件执行。
  • 32位ARM和Thumb指令:32位Thumb指令带有.w后缀。
  • 桶式移位器 (barrel shifter) 是ARM模式的另一个独特功能。它可以用于将多个指令缩小为一个。比如,你可以使用左移,而不是使用两条指令将寄存器乘以2并使用mov将结果存储到另一个寄存器中: mov r1, r0, lsl #1 ; r1 = r0 * 2

ARM指令简介

汇编语言由指令构成,而指令是主要的构建块。ARM指令通常后跟或两个操作数,并且通常使用以下模板

MNEMONIC {S) {condition){Rd],Operand1,Operand2

注意,由于ARM指令集的灵活性,并非所有指令都使用模板中提供的所有字段。其中,条件字段与CPSR寄存器的值紧密相关,或者确切地说,与寄存器内特定位的值紧密相关

Operand2被称为灵活操作数,因为我们可以以多种形式使用它,例如我们可以将这些表达式用作Operand2:

文本, 信件

描述已自动生成

下面以一些常见指令为例::

文本, 信件

描述已自动生成

表格

描述已自动生成

图示

中度可信度描述已自动生成

posted @ 2023-06-18 01:19  N0t3  阅读(248)  评论(0编辑  收藏  举报