ARM汇编学习笔记

本博客根据广州大学汇编课程进行总结,以方便学习和复习。
摘要由CSDN通过智能技术生成

【笔记来源:广州大学汇编课程】

一、处理器结构和汇编语言

1.1 计算机语言

1.高级语言
主要是设计应用程序,有良好的库和模组,方便调用和代码的快速实现。
C/C++、java、python、C#、JS、…

2.汇编语言
底层语言,是直接和硬件(处理器的寄存器)打交道的。
汇编语言是和处理器的架构相关的----不同架构的处理器,汇编语言是不一样的。

3.机器语言
机器语言是二进制的机器码。处理器真正执行的代码。

1.2 汇编语言的特点

  1. 直接和硬件打交道,代码的执行效率比较高
//C语言
void delay(void)
{
   
	int i=0x1000;
	while(i--);
}
//高级语言:Linux
void delay(void)
{
   
	sleep(2);
}
//汇编语言:
delay:
	mov r4, #0x1000
temp:
	sub r4,r4,#1
	cmp r4,#0
	bne temp
	mov pc,lr
  1. 汇编语言比较节省内存。
    现在汇编语言应用的场合:8位的单片机
  2. 有些场合用高级语言是实现不了的,必须用汇编语言
    例如:处理器的初始化,内存初始化,stack初始化、中断的响应过程等。----BIOS程序或者嵌入式平台启动引导程序。
  3. 记很多汇编指令,代码编写效率低,不能使用现成的库。

1.3 处理器架构

每一种架构的处理器都有它的汇编语言,不同架构之间的汇编语言是不通用的,所以汇编语言是和处理器的架构是相关的。
1、处理器—PC平台
CPU ---- Central Process Unit 。
x86 ---- intel 和 AMD
PowerPC ---- nxp(恩智浦)

2、嵌入式微处理器
MPU ---- Micro Process Unit
ARM ----- ARM公司
RISC-V ---- 相当于Linux,开源免费
Coldfile ---- NXP
MIPS---- ARM公司

3、控制器—单片机
MCU — Micro Control Unit
通常是8位的,做一些简单的控制。
51单片机
AVR单片机
STM8单片机
PIC单片机

1.4 什么是ARM?

ARM公司–>华为海思—>台积电(ASML光刻机)–>麒麟处理器–>华为手机

  1. ARM是一种处理器的架构
    ARM— Advanced RISC Machine 高级的精简指令集计算机系统的机器。
    总部英国剑桥。ARM—>softbank—>Navid(英伟达)
  2. ARM也是一家公司的名字
  3. ARM公司只设计处理器的架构,不生产芯片。
    设计ARM芯片的公司:三星、高通、博通、恩智浦、Atmel、海思、…

ARM的中文名—安谋

1.5 ARM处理器的系列

1.V4T
ARM7
ARM9

2.V5TE
ARM10

3.V6
ARM11

4.V7
cortex-A8
Cortex-A9
Cortex-A15

5.V8------>8核64bits处理器。
ARM的内核:Cortex-A53、Cortex-A55,Cortex-A72/A73、Cortex-A77.

实验室:
ARM—>V8—>Cortex-A53—>S5P6818–>samsung

1.6 ARM的框架

以S5P6818处理器为例:
在这里插入图片描述


二、计算机平台的硬件功能

1、处理器
程序的运行、数据的处理、接口控制。
S5P6818 ----- 1.4GHz * 8

2、硬盘(电子硬盘–存储内存)
存放数据和代码,但是代码和数据不能在硬盘上运行和处理。硬盘上的数据掉电不丢失,可以永久保存。

辅助存储器—SD卡、U盘、移动硬盘
eMMC-----8GB

3、内存(运行内存–DDR3)
存放正在处理的数据和正在执行的代码。
DDR2 ---- 1GB

4、接口
液晶屏、触摸屏、串口、网口、声音接口、SD卡、USB、LED指示灯、蜂鸣器、按键、ADC、摄像头、看门狗。

ARM处理器的特点
体积小、功耗低、集成度高、成本低、高性能

2.1 数据类型

struct test {
	char a;
	int b;
	short c;
	long d;
};
sizeof(struct test) = ?

在这里插入图片描述

基本数据类型的大小
应用环境的位数
数据在内存中存放的时候,有一个对齐的要求

如果在32 bits环境下,这个结构体的大小:1+4+2+4 = 11B(错误

1、基本数据类型
字节类型 ---- char ---- 1B
半字类型 ---- short ----2B
字类型 ---- int ------4B
长字类型 ---- long ----- 和处理器的字长保持一致

2、数据对齐的概念
数据是放在内存中,内存中每一个存储空间都有一个地址。针对内存来讲,是通过地址来访问内存中的内容的。
对于存储器来讲,一个地址对应的存储空间一个字节。
数据放到内存中,并不是任意一个地址都可以存放该数据的。地址需要满足一定的对齐要求。
char----任何一个地址都可以存放该数据
short----地址除以2可以整除
int ----地址除以4可以整除
long ----- 地址除以4/8可以整除(需要看处理器的字长)

2.2 数据存储格式

  • 存储器:一个存储空间对应一个地址,每个空间存放的数据是一个字节。
  • 最常见的数据类型—int型,处理器中,寄存器的地址一般是32bits的,寄存器的内容也还是32bits

问题
一般我们处理的数据是32bits的数据(地址),是4字节的,该数据存放在内存中的时候,需要4个地址空间---->高字节的数据放在高地址还是放在低地址。

  • 大端格式/大尾格式
    高字节的数据存放到低地址,低字节的数据存放到高地址
  • 小端格式/小尾格式
    高字节的数据存放到高地址,低字节的数据存放到低地址
    方法1:
    unsigned int a=0x12345678;
    char *p = &a;
    *p == 0x12 ---->大端格式
    *p == 0x78 ---->小端格式
    方法2:
    地址 数据
    (*(unsigned int*)0x40000000) = 0x12345678;
    大端格式:
    (*(unsigned char *)0x40000000) == 0x12;
    (*(unsigned char *)0x40000001) == 0x34;
    (*(unsigned char *)0x40000002) == 0x56;
    (*(unsigned char *)0x40000003) == 0x78;

小端格式:
(*(unsigned char *)0x40000000) == 0x78;
(*(unsigned char *)0x40000001) == 0x56;
(*(unsigned char *)0x40000002) == 0x34;
(*(unsigned char *)0x40000003) == 0x12;

在这里插入图片描述

2.3 ARM的寄存器

由两部分组成的
1、ARM内核中的寄存器—ARM公司

  • 通用寄存器—所有的ARM处理器都是一样(ARM的版本相关)
    只能通过寄存器的名字来访问,只能使用汇编语音进行编程
    通用寄存器:R0~R15和CPSR、SPSR

2、ARM外设模块的寄存器----samsung公司

  • 特殊功能寄存器-----与具体的ARM芯片相关的
    只能通过寄存器的地址来访问,可以使用汇编语言编程,也可以使用C语言编程

在这里插入图片描述

2.3.1 ARM的寄存器(内核中的寄存器)

  • 通用寄存器:R0~R15

寄存器的常用方法
1、R0~R3
R0~R3----参数的传递和返回值,多余4个的参数用数据stack来传递。
例:

//main.c
extern int add_xy(int x, inty);
void main(void)
{
   
	int sum;
	int a=10,b=20;
	sum = add_xy(10,20);
	printf("sum = %d\n", sum);
}
//add.S
add_xy: //x和y怎么处理--->第一参数->R0,第二个参数->R1
	add R3,R1,R0 //R3=R1+R2
	mov R0,R3 //R0=R3
	mov PC,LR //子程序的返回。将返回地址(LR)传送到程序计数器(PC)

2、R4~R12:存放局部变量
如果局部变量比较多,局部变会存放在stack中。register关键字定义的局部变量优先存放在寄存器中。
提示:
C语言中的关键字:extern、const、register、volatile、static

int a=100int b;
const int e=20
int main(void)
{
   
	int c;
	int d;
	int *p;
	c = a + 10;
	b = 20;
	d = b + e;
	p = malloc(100);
	*p = 1;
	*(p+1) = 2;
	free(p);
	return 0;
}

在这里插入图片描述

3、R13
R13寄存器有一个别名叫SP—Stack Pointer寄存器中存放的是stack顶的地址。在处理器初始化的时候,会对stack进行初始化,让它等于内存的某个地址。
4、R14
R14寄存器有一个别名,叫LR—Link Register,保存子程序的返回地址
例:
test程序中,调用了子程序fun,fun自程序执行结束后,会返回test。

test:
	---------
	---------
	BL fun //调转到fun子程序的同时,保存返回地址到LR寄存器
	--------- //这条指令在内存中的地址是fun子程序的返回地址
	---------
fun:
	---------
	---------
	MOV PC,LR //将返回地址LR传递给PC寄存器,实现子程序的返回。

5、R15
R15寄存器有一个别名–PC(Program Counter),存放正在执行语句的地址
例:
MOV PC ,#0x00000000
相当于处理器重启。针对ARM处理器来讲,ARM启动的时候,执行的第一条指令在0x00000000地址。
R3 = R2+R1;//C语言不能直接访问通用寄存器,需要使用汇编语言访问。

2.3.2 状态寄存器

1、CPSR ---- 当前程序状态寄存器
CPSR ----- Current Program Status Register
反应当前处理器的状态:

  • M[4:0]—工作模式(mode,7种)。
    • 通过这个5个位可以获取处理器的工作模式。也可以通过这5个位来设置处理器的工作模式。
  • T—工作状态(state,2种)ARM处理器一般有两种工作状态,分别是:
    • ARM----- ARM处理器在执行32bits的机器码— 提高指令的执行效率
    • Thumb-----ARM处理器在执行16bits的机器码—节省内存空间,降低功耗。
    • 通常情况下,ARM处理器是执行32bits的机器码,处于ARM工作状态。处理器刚开始启动的时候,处于ARM状态。
    • T–1 Thumb state
    • T–0 ARM state
  • 中断的开关(中断有两种类型:FIQ—Fast Interrupt reQuest,IRQ—Interrupt ReQuest )
    • F—FIQ中断的使能位
      • FIQ快速中断
      • F–1 disable屏蔽
      • F–0 enable
    • I—IRQ中断的使能位
      • IRQ是一般中断,优先级和响应时间是低于FIQ的。
      • I—1 disable
      • I—0 enable
  • 算术运算的时候,运算的结果:是否是整数,是否为0,是否有进位,是否有借位。----状态标志位。
    • NZCV—条件码标志位
    • 算术运算指令的运算结果可以影响条件码标志位。有条件的汇编指令可以通过条件码标志位来判断是否要执行。
    • 例子:
if(a==10)
	a=a+1;
else
	a=a-1;
	
CMP R4,#10 //R4里面存放了常数10 CMP---compare,会影响NZCV
ADDEQ R4,R4,#1//R4=R4+1,EQ--EQual
SUBNE R4,R4,#1

ARM汇编指令可以带条件,条件满足就执行,条件不满足,就是一个空指令(NOP)。

CMP R4,#10
SUBS R5,R4,#10//R5=R4-10,运算的影响标志位。

CPSR寄存器:
在这里插入图片描述

2、SPSR ---- 备份程序状态寄存器
在ARM处理器在工作模式切换的时候,用来保存CPSR。

2.3.3 ARM的工作模式

工作模式----Operating Mode,ARM处理器在处理不同的功能所处于的工作模式。
1、用户模式:ARM处理器在运行应用程序的时候
2、FIQ模式:ARM处理器正在处理快速中断的时候
3、IRQ模式:ARM处理器正在处理器一般中断的时候
4、管理模式:处理器进入保护模式,一般我们设置cache、设置MMU需要在管理模式,ARM在启动的时候,也是出于管理模式。
5、中止模式:处理器运行程序的过程中的一种出错模式。访问的地址不存在,后者地址禁止访问。
6、系统模式:处理器在运行操作系统应用程序时候的一种工作模式。
7、未定义模式:ARM处理器在执行汇编指令(机器码),是没有办法译码,指令未定义。出现未定义的问题:新版本的扩展指令应用到老版本的处理器上;指令在存储或者读取的过程中出错。

2.4 S5P6818处理器

在这里插入图片描述

三、ARM汇编指令

ARM汇编指令的应用场合:
ARM处理器最开始的启动代码、对处理器内核中的模块进行设置(如:cache、MMU、协处理器)、stack初始化(MOV SP, #0x70000000)、中断的进入和退出、任务的调度。
计算机系统的底层代码才用到汇编,往往底层代码都是做好的。

3.1 数据处理指令

只能完成通用寄存器(R0~R15)和立即数(常数前面加#)之间的运算。

1)算术运算指令–ADD、SUB
2)位运算指令—AND、ORR、BIC、EOR
3)比较指令----CMP、TEQ、TST
4)数据传送指令----MOV
注意:并不是所有的立即数都是直接使用在数据处理指令中。如果立即数不合法,可以使用LDR指令来替代。

ADD R1,R0,#0x11FF //不合法

替代:

LDR R2,=0x11FF
ADD R1,R0,R2

3.2 数据传送指令

MOV R1,R0 //将R0的值传输给R1
MOV R1,#20 //将20传送给R1
MOV R1,R0 ,LSL #3 //R1=(R0<<3)
//MVN----取反后再传送。
//不合法:
MOV 10,R1
MOV R1,CPSR //操作CPSR有专门的指令
MOV R1,#2 ,LSL #3 //R1=(2<<3)

3.3 算术运算指令

<<—LSL,>>—LSR, &—AND, |—ORR, ^----EOR(异或)
~&----BIC(位清除)

ADD R3,R2,R1//R3=R2+R1
ADD R3,R2,#30 //R3=R2+30
SUB R0,R1,R2 //R0 = R1 - R2
AND R3,R2,R1 //R3=R2&R1
/*思考:
&与&&
|与||
!与~
<<与>>
^---异或*/
//不合法:
ADD R3,#30,R1
ADD R3,#2,#1----> MOV R2,#2
		    ADD R3,R2,#1

位运算的例子:
1)unsigned int a,将a的第10位置1,其他位保持不变。
清0—和0进行按位与运算
置1—和1进行按位或运算

//C语言
 a = a | 0x400
 a |= 0x400
 a |= (1<<10)
//汇编语言
ORR  R4,R4,#0x400
ORR  R4,R4,#(1<<10)
MOV  R5,#1
ORR  R4,R4,R5, LSL #10

2)unsigned int a,将a的第10位清0,其他位保持不变。

//C语言:
	a = a & ~1<<10)
	a &= ~(1<<10)
//汇编语言:
	BIC R4,R4,#0x400
	BIC R4,R3,#(1<<10)
	
	MOV R5,#1
	BIC R4,R4,R5,LSL #10
	
	AND R4,R4,#FFFFFDFF //不合法,立即数超出了范围

3)unsigned int a,将a的第10位取反,其他位保持不变。

//C语言:
	a ^= (1<<10)
//汇编语言:
	EOR R4,R4,#(1<<10)
	
	MOV R5,#1
	EOR R4,R4,R5,LSL #10

大疆笔试题:
有一个32bits的寄存器REGn,寄存器的地址是0x1F000010,写一个安全的函数实现将REGn的指定位反转,其他位保持不变。
思考:
将一个32bits的数0x12345678,写到一个地址为0x40000000的内存中。
*(unsigned int *)0x40000000 = 0x12345678

int regn_toggle(unsigned int x)
{
   
	if(x<0 || x>31)
		return -1;
	P()
	*(volatile unsigned int *)0x1F000010 ^ = (1<<x);
	return 0;
	V()
}
//汇编:
LDR R1,=0x1F000010 //R0=0x1F000010.MOV R1,#0x1F000010非法
LDR R0,[R1]//读出0x1F000010地址下的内容
EOR R0,R0,#(1<<10)
STR R0,[R1]

3.4 比较指令

  • CMP R1 ,#100 ;将寄存器 R1的值与立即数100相减,并根据结果设置CPSR的标志位(NZCV)。
  • CMN R1, R0 ;将寄存器 R1 的值与寄存器 R0 的值相加,根据结果设置 CPSR 的标志位。
  • TST R1 ,#0xffe ;将寄存器R1的值与立即数0xffe 按位与,并根据结果设置 CPSR 的标志位。、
  • TEQ R1 ,R2 ;将寄存器 R1 的值与寄存器 R2 的值按位异或 ;并根据结果设置 CPSR 的标志位,比较R1与R2是否相等

思考:
4)unsigned int a,判断a的第10位是否1?

//C语言:
if(a == (1<<10))if(a &1<<10)if(a & (1<<10) == (1<<10))错:==优先级高于&  ----if(a&1)
if((a & (1<<10)) == (1<<10))//汇编语言:
TST R4,R4,#(1<<10) //逻辑运算的结构是存放在NZCV中

数据处理指令包括:传送指令、算术运算指令、位运算指令、比较指令。比较指令可以自动影响标志位,如果其他的数据处理器指令要影响标志位需要在指令后面加一个“S”。

void delay(void)
{
   
	int data=0x10000;
	while(data--);
}
//汇编1:
delay:
	MOV R1,#0x10000
tmp:
	SUB R1,R1,#1
	CMP R1,#0  //比较指令,会自动影响标志位。
	BNE tmp
	MOV PC,LR
//汇编2:
delay:
	MOV R1,#0x10000
tmp:
	SUBS R1,R1,#1 //s---会自动影响标志位。
	BNE tmp
	MOV PC,LR

难点
数据处理指令中,会经常用到立即数,如:
MOV R0,#0x10000
ADD R1,R0,#0xFF00
BIC R1,R1,#(1<<10)
CMP R4,#0x100
注意:立即数并不是所有的数值都是合法的。主要是受到机器码编码位数的限制。在机器码中,给立即数的位数只有12bits。合法立即数的要求:
1、如果立即数的值是小于256,也就是可以使用8bits数来描述的。
如:100,200,80,250
2、如果一个立即数大于等于256,如果该立即数循环左移偶数位可以得到一个小于256的数,则该立即数是合法的。
0xFF00 —>0x0000FF00—>循环左移24bits得到0x000000FF。
0x101非法—>0001 0000 0001

设计程序的时候,如果要操作非法的立即数,如何处理?
使用LDR指令。
如:将0x1F000010传送到R1


                
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
嗨!对于逆向学习汇编语言的学习笔记,我可以给你一些基本的指导。首先,汇编语言是一种低级语言,它与计算机的底层硬件密切相关。逆向工程则是通过分析和理解已编译的程序来获取程序的内部信息。 以下是一些学习汇编语言和逆向工程的建议: 1. 学习基础知识:了解计算机体系结构、寄存器、内存和指令集等基础概念是必要的。可以先阅读相关的书籍或在线教程,掌握这些基本概念。 2. 掌握汇编语言的语法和指令集:每种计算机体系结构都有自己的汇编语言语法和指令集。选择一种你感兴趣的体系结构(如x86、ARM等),并学习它的汇编语言。 3. 练习编写和调试汇编代码:通过编写简单的汇编代码来熟悉语法和指令集。使用调试器来单步执行代码并观察寄存器和内存的变化。 4. 分析已编译程序:选择一个目标程序进行逆向分析。使用反汇编器将程序转换为汇编代码,并分析代码的逻辑和功能。这有助于理解程序的结构和运行过程。 5. 使用调试器进行动态分析:通过调试器来动态地执行程序,并观察程序在运行时的行为。使用断点、内存查看器和寄存器查看器等工具来分析程序的状态和数据。 6. 学习逆向工程工具和技术:了解常用的逆向工程工具和技术,如IDA Pro、OllyDbg、Ghidra等。掌握这些工具的使用可以提高你的逆向分析能力。 7. 参考优秀资源:阅读与逆向工程和汇编语言相关的书籍、论文和博客,关注相关的社区和论坛。与其他逆向工程师交流经验也是很有帮助的。 记住,逆向工程是一个需要耐心和实践的过程。持续学习和实践将帮助你提高逆向分析的技能。祝你在学习汇编语言和逆向工程的过程中取得好成果!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值