内容纲要

ARM汇编基础

ARM(Advanced RISC Machine)
NDK使得开发人员可以通过C/C++代码来编写软件的核心功能代码,这些代码通过编译会生成基于特定处理器的可执行文件,对于使用ARM处理器的Android手机来说,它最终会生成对应的ARM elf可执行文件

汇编指令

STMFD:把寄存器的值亚入堆栈(push)
STMFD SP!,{R11,LR} 将R11,LR寄存器的值压栈
LDMFD:从堆栈恢复寄存器的值(pop)
ldmfd sp!,{fp,pc} 恢复fp寄存器,并将lr寄存器值赋给pc寄存器
STR:写入数据到存储器中
STR R1,[R11,#var_C] 将R1寄存器的值保存到栈变量var_C中
LDR:从存储器中读数据
BL:带链接跳转指令(call)
BL puts 调用puts函数

原生程序的生成过程

gcc:交叉编译器(能在一种平台上编译出另一种平台上运行的程序的工具集合)
原生程序采用C/C++编写,gcc编译后,变成了ARM汇编代码。
四过程:预处理,编译,汇编,链接

基础知识

ARM汇编语言与C语言公用一套原生程序开发的API接口,两者都是基于模块化的面向过程的编程思想。C语言能实现的功能ARM汇编语言都能实现。
ARM微处理器共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器。
ARM处理器支持7种运行模式:
IMG_1095
ARM处理器有2种工作模式:

IMG_1096

IMG_1097

ARM编写注释:/ /和@
ARM汇编规定:R0-R3这四个寄存器用来传递函数调用的第1-第4个参数,超出的参数通过堆栈传递。R0寄存器同时用来存放函数调用的返回地址。

ARM寻址方式

立即寻址
寄存器寻址
寄存器移位寻址:
LSL:逻辑左移,低位补0
LSR:逻辑右移,高位补0
ASR:算术右移
ROR:循环右移
RRX:带扩展的循环右移,移出的空位用C标志的值填充
寄存器间接寻址
基址寻址
多寄存器寻址
IMG_1098
堆栈寻址:
LDMFA_STMFA、LDMEA_STMEA、LDMFD_STMFD、LDMED_STMED。
stmfd sp!,{r1-r7,lr} 将r1-r7,lr入栈
块拷贝寻址
LDMIA_STMIA、LDMDA_STMDA、LDMIB_STMIB、LDMDB_STMDB。
ldmia r0!,{r1-r3} 从r0寄存器指向的存储单元中读取3个字(32位)到r1-r3寄存器
相对寻址

ARM与Thumb指令集

image-20210703141408480

简述

image-20210703141841656

image-20210703142128751

引用:https://zhuanlan.zhihu.com/p/109537645

详细指令分析:https://blog.csdn.net/mickey35/article/details/82011449

《Android安全》P173-P185

IMG_1110

IMG_1111

IMG_1112

IMG_1113

IMG_1114

IMG_1115

IMG_1116

IMG_1117

IMG_1119

IMG_1120

IMG_1121

IMG_1122

IMG_1123

汇编器指令

程序中所有以”.“开头的指令都是汇编器指令。
.file:指定源文件名
.align:指定代码对齐方式
.align 4表示2^4=16字节
.ascii:声明字符串
.global:声明全局符号
.type:指定符号的类型
.type main,%funciton表示main符号是函数
.word:用来存放地址值
.word .LC0-(.LPIC0+8)
.size:设置指定符号的大小
.size main,.-main “.”表示当前地址,减去main符号的地址即为整个main函数的大小
.ident:编译器标识