ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同 

0x00 本文目标

本文内容从《ARM Architecture Reference Manual》中截取翻译,可以看作是一个重点笔记集。仅记录博主认为有意思的部分,并加入一些个人理解。如果发现有不对的地方欢迎留言指正。
现代的智能手机是能进行ARM汇编级别交互的最便捷的设备,因此实例分析的内容基于博主的小米Note+IDA,和某个正在被调试的安卓程序。该程序加载的SO文件使用armeabi架构。
0x01 ARM模型与概念

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM支持三种数据类型的读写:Byte(8 bits),Halfword(16 bits),Word(32 bits)。所有内存指令相关的读写操作都会基于这三种数据类型。

ARM使用小端存储,这意味着例如指令E5 9F 00 90在内存中会反序存储为:

0x00a0 90 00 9F E5

在读取指令后,会被还原为正序E59F0090。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

 

ARM一共支持7种处理器模式,程序在编译后所运行的绝大部分时间片中,例如执行了一段MD5加密函数,都处于usr模式。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

寄存器示例图,某个程序正在处于调试暂停中。

ARM处理器一共有37个之多的寄存器。在所有的ARM状态模式中,有15个可见寄存器(R0~R14),和1~2个状态寄存器随时可编程交互。其余没有提到的寄存器,用于处理异常、中断等核心指令,外部不可见也不能自主控制读写。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

R0~R7作为不保留寄存器,可以*编程指定其含义。例如R0~R3最常用于参数传递,返回值等保存。

R8~R14是保留寄存器,有自己的特殊含义,在寄存器实例图中可以看到多半保存和地址相关的值,又或者指向了SP地址或LR地址。

通常R13就是SP(Stack Pointer)寄存器,该值指向当前汇编代码段可以使用的栈起始地址。R14作为LR(Link Register)寄存器,保存当前汇编代码段执行完毕后,需要回溯到的汇编代码地址。PC程序计数器是一个特殊的寄存器,指向当前正在执行的代码地址。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

PSR标志寄存器,也就是寄存器实例图右边的对usr用户模式有意义的NZCVQFTMODE标志位,对程序的分支结构执行,运算的结果产生影响。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

N(Negative)标志位当运算结果为负数时值为1。Z(Zero)标志位当运算结果为0时值为1。C标志位有多个用途,其中当执行CMP等比较指令时,用1和0分别代表真假。

0x01 汇编指令与机器码

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM标准模式下的指令集的机器码编码位结构一共有32位,由几个通用部分组成:条件码,识别码,操作标识码,操作数(立即数、地址数等,编码内容看指令的具体含义)。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

其中识别码[27:25]的值用于区分指令类别,下图实例拆解一条指令:

在对应的位表示中识别码[27:25]的值是010,对应指令集编码结构图可以定位到这是一条Load/store immediate offset(立即读取存储偏移量)指令。在对其他的位进行翻译后可以得到原始汇编指令:ldr r0, [pc, #0x90]。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

常用的指令集类别有:读取存储指令,流程控制指令,运算指令。

存储指令可以将寄存器的值保存到内存地址中,读取指令将内存地址保存到内存中。常见于STR和LDR。例如下图0x1234地址指令分别将R1和R0的值保存到栈中,随后又从程序地址中使用LDR指令再次赋值R0,R1寄存器。在汇编级别的底层内存结构读写时还有一个内存对齐问题,如果内存不对齐将会出现性能低下、程序崩溃、操作结果不可预料等后果。所以读写的目标地址永远保持4的倍数是最佳,如果需要对已经生成的汇编指令去修改,那么也需要保持这一原则。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

此外,LDR指令读取固化程序数据时还存在一个绝对偏移问题,在内存对齐的情况下,实际的偏移地址为(立即操作数+8)。下图‭B380A1B4‬地址的机器码为E59F51D4,拆分机器码编码后可以得到汇编指令LDR R5, [PC, #0x1D4],当前PC值为0xB380A1B4,+0x1D4=0xB380A388,再加上绝对偏移地址量8即0xB380A390地址值,与IDA反汇编的语句值一致。(这里有个疑点不知是只有博主手机这样还是所有的ARM设备都存在这一规则。)

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

机器码[31:28]控制条件语句,例如常用的BNE不相等跳转的机器码[31:28]=0001。

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

ARM指令《ARM Architecture Reference Manual》和ARMv7-M Architecture Application Level Reference Manual不同

数据处理指令及其机器编码格式。《ARM Architecture Reference Manual》往后的内容都相似,对每个bit位的含义进行了详细说明,博主就不机械复制粘贴了。如果你想要继续学习命令列表,如MOV, ADD等可以继续阅读手册,传送门地址:https://download.csdn.net/download/dxcyber409/11250918

 
————————————————
版权声明:本文为CSDN博主「DXCyber409」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/DXCyber409/article/details/92838715

上一篇:【asp.net core 系列】6 实战之 一个项目的完整结构


下一篇:【Rust日报】2020-09-21 Rust宣布成立错误处理项目组