这里是非虫笔记本,对学习知识的一种总结。有机会可以一起学习。

ARM汇编(非虫笔记)

1.ARM汇编的目的:

分析elf文件的需要。

2.原生程序生成过程。

(1)预处理,编译器处理c代码中的预处理指令。

gcc -E hello.c -o hello.i

(2)编译 gcc编译器首先要检查代码的规范性,以及是否有语法错误,在检查无误之后,gcc编译把代码翻译成ARM汇编语言的代码。

gcc -S hello.i -o hello.s

(3)汇编,gcc编译器会挑用汇编器将汇编代码汇编成二进制目标文件。

gcc -c hello.s -o hello.o

(4)链接,这个阶段会调用链接器将二进制的目标文件链接成android平台可执行的ARM远程程序。

gcc hello.o -o hello

3.ARM知识了解

(1)与JAVA的区别:

ARM汇编语言是一门”低级”语言可以和系统的底层相互沟通。

(2)ARM汇编语言编写的程序运行速度快,占用内存少

(3)缺点是编写的代码难懂,难以维护。

(4)ARM汇编语言,c语言能实现的ARM汇编语言都能实现。

(5)ARM具有31个通用寄存器,6个状态寄存器

(6)ARM处理器支持其中运行模式。

1. 用户模式:ARM处理器正常的程序执行状态。
2.快速中断模式:用于高速数据传输或通道处理。
3.外部中断模式:用于通用的中断处理。
4.管理模式:操作系统使用的保护模式。
5.数据访问终止模式:当数据或指令预取终止时进如该模式,可用于模拟存储及存储保护。
6.系统模式:运行具有特权的操作系统任务。
7.未定义指令中止模式:当未定义的指令执行时进入该模式。

4.ARM汇编语言程序结构

(1)处理器架构定义

.arch armv5te @处理器架构
.fpu softvfp  @协处理器类型
.ebi_attribute 20,1 @接口属性
.ebi_attribute 21,1
.ebi_attribute 23,1
.ebi_attribute 24,1
.ebi_attribute 25,1
.ebi_attribute 26,1
.ebi_attribute 30,1
.ebi_attribute 18,1
.arch指定了ARM处理器架构。
.armv5te表示本程序在armv5te架构处理器上运行。
.fpu指定了协处理器的类型。
softvfp表示使用浮点运算库来模拟协处理运算。
.ebi_attribute 指定了一些接口属性。

(2)段定义:

.section 定义只读数据,属性是默认
.text 定义了代码段。
因为之前读过了8086王爽的汇编,所以对段的理解很轻松。

(3)注释与标号

注释方法://多行注释,@单行注释
标号:<标号名>:
eg:
    loop:
    ...
    end loop
标号和8086汇编很类似。

(4)汇编器指令

程序中所有以”.”开头的指令都是汇编指令,他们不属于ARM指令集。
部分会汇编器指令:
.file: 制定了源文件名。
.align:代码对其方式。
.ascii:声明字符串。
.global:声明全局变量。
.type:指定符号的类型。

(5)字程序与参数传递。

声明函数的方法:
.global 函数名
.type  函数名,%function
函数名:
    <...函数体...>
声明一个实现两个数相加的函数的代码
.global MyAdd
.type MyAdd,&function
MyAdd:
    add r0,r0,r1 
    mov pc,lr
ARM汇编规定:R0-R3这4个寄存器用来传递函数调用的第1到第4个参数,超过的参数通过堆栈来传递。

(6)ARM处理器寻址方式

1.立即寻址。
mov R0,#1234 @# z作为前缀,表示16进制时以"0x"开头
2.寄存器寻址。
mov R0,R1
3.寄存器移位寻址。
五种移位操作:

(1)LSL:逻辑左移,移位后寄存器空出的低位补0
(2)LSR:逻辑右移,移位后寄存器空出的高位补0
(3)ASR:算数右移,移动过程中符号位不变。如果操作数是整数,则移位后空出的高位补0,否则补1
(4)ROR:循环右移,移位后移出的低位填入移位空出的高位。
(5)RRX:带扩展的循环右移,操作数右移移位,移位空出的高位用C标志的值填充。
eg:

mov R0,R1,LSL #2
4.寄存器间接寻址
LDR R0,[R1]
5.基址寻址
LDR R0,[R1,#-4]
6.多寄存器寻址
LDMIN R0,{R1,R2,R3,R4}
LDM 是数据加载命令
指令的后缀IA表示每次执行完成加载操作后R0寄存器的值自增1
ARM中,字表示的是一个32位。
R1=[R0]
R2=[R0+#4]
R3=[R0+#8]
R4=[R0+#12]
Ps:这里+#4的原因是因为32位占4个字节。
7.堆栈寻址。
STMFD SP!,{R1-R7,LR} 入栈,多用于保存子程序“现场”
LDMFD Sp!,{R1-R7,LR} 出栈,多用于回复子程序的现场
8.块拷贝寻址。

块拷贝可实现连续地址数据从存储器的某一位置拷贝到另一位置。

LDMIN R0!,{R1-R3} @从寄存器指向的存储单元中读取3个字到R1-R3寄存器。
9.相对寻址 。

相对寻址一程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到的操作数的有效地址。

5.简单的实例程序hello分析

EXPORT main  //BubblePig  表明这个main函数是被程序导出的
    Main    //main为函数的名称。JDA Pro能自动识别原生程序中所有的函数及其名称
var_C= -0xC  //栈变量
Var_8= -8       //栈变量
    STMFD SP!,{R11,LR} //函数的指令部分 STMFD和LDMFD是堆栈寻址指令,STMFD用于把寄存器压入栈中。LDMFD指令用于从占中回复寄存器的值。
ADD R11,sp, #4  //加法指令
SUB sp,sp,#8        //减法指令
STR R0,[R11,#var_8] //STR和LDR是存储器访问指令
STR R1,[R11,#var_C] //STR是写存储指令
LDR R3,={aHelloArm-0x8300}
ADD R3,PC,R3 ; “Hello ARM!”
MOV R0,R3 ;s //数据传送
BL puts //BL为带连接的跳转指令。就是执行该命令。
MOV R3,#0
MOV R0,R3
SUB SP,R11,#4
LDMFD SP!,{R11,PC}

以上指令相当于:

incldue <stdio.h>
Int main(int argc,char* argv[]){
Printf(“Hello ARM!\n”);
Return 0 ;
}

6.跳转指令

6.1 B跳转指令

B{cond}label
B指令属于ARM指令集,是最简单的分支指令。当执行B指令时,如果条件cond满足,ARM处理器立即跳转到label指定的地址处急需执行。

6.2 BL带链接的跳转指令

BL{cond}label
当执行BL指令时,如果条件cond满足,会首先将当前指令的下一条指令的地址拷贝到R14寄存器中,然后跳转到lable指定的地址处急继续执行。

6.3 BX 带状态切换的跳转指令

BX{cond}Rm
当执行BX指令时,如果条件cond满足,则处理器会判断Rm的位[0]是否为1,如果为1则跳转时自动将CPSR寄存器的标志T置位。并将目标地址处的代码解释为Thumb代码来执行,处理器会切换至Thumb状态。反之,Rm的位[0]位0,则跳转时自动将CPSR寄存器的标志T复位,并将目标地址处的代码解释为ARM代码来执行。

6.4 BLX带链接的状态切换的跳转指令。

BLX{cond}Rm
BLX指令集合了BL与BX的功能,当条件满足时,除了设置链接寄存器,还根据Rm位[0]的值来切换处理器状态。

7存储器访问指令

7.1 LDR用于从存储器中加载数据到寄存器中

LDR{type}{cond}Rd,label
LDRD{cond}Rd,Rd2,label

7.2 STR 用于存储数据到指定地址的存储单元中。

STR{typr}{cond}
STRD{cond}Rd,Rd2,label

7.3 LDM 可以从指定的存储单元加载多个数据到一个寄存器列表。

LDM{addr_mode}{cond}Rn{!}reglist

7.4 STM

将一个寄存器列表的数据存储到指定的存储单元。

7.5 PUSH 入栈

7.6 POP 出栈

7.7 SWP

SWP用于寄存器与存储器之间的数据交换。

8. 数据处理指令

8.1 MOV 传值

8.2 MVN 数据非传送指令

将8位的立即数或寄存器按位取反后传送到目标寄存器中。

8.3 ADD 加法指令

8.4 ADC 带进位加法指令

8.5 SUB 减法指令

8.6 RSB 逆向减法指令

8.7 SBC 带进位减法指令

8.8 RSC 带进位逆向减法指令

8.9 MUL 为32位乘法指令

8.10 MLS指令将Rm寄存器和Rn寄存器中的值相乘,然后再从Ra寄存器的值中减去乘积,最后将所得结果的低32位存入Rd寄存器汇总。

8.11MLA 将Rm寄存器和Rn寄存器的值相乘,然厚再从Ra寄存器的值相加,最后将所得结果的低32位存入Rd寄存器中。

8.12 ASR 算数右移指令

8.13 AND 逻辑与指令

8.14 ORR 逻辑或指令

8.15 EOR 异或指令

8.16 BIC 位清楚指令

8.17 LSL逻辑左移指令

8.18 LSR 逻辑右移指令

8.19 ROR 循环右移指令。

9 其他指令

9.1 中断指令

9.2 NOP 空操作指令

9.3 MRS 读状态寄存器指令

9.4 MSR 写状态寄存器指令