ARM开发之汇编语言

----向一个寄存器中一个值添加100(立即数,即常量)--------
X89:add eax,#100(eax寄存器)
68K:ADD #100,D0(68K是摩托罗拉的)
ARM:add r0,r0,#100

------------从一个寄存器指针加载到寄存器--------
X86: mov eax,DWORD PTR[ebx]
68K:MOVE .L (A0),D0
ARM:ldr r0,[r1]

ARM汇编指令格式

Operation{congd} 【s】 RD , RN, operand2
操作 条件 状态 目标寄存器 源寄存器 后续附加操作
ADD R1 ,R2,#100 把R2加100存到R1例

汇编的入口(类似C的int main)
AREA example, CODE, READONLY
表示代码区域 名字 表明是代码 只读
ENTRY(入口)
CODE32(表示32位代码)
START
。。。
.。。。
END

条件位
在这里插入图片描述
状态位 v
在这里插入图片描述

立即数要求不同,比如有的芯片要求12位的立即数,8位表示立即数,剩下4位用来循环移位。那这个立即数必须能被4整除且得到的结果在0-255之间才有效。因为要移位,想到与除2的N次方。因此要求能被4整除

ADD 和MOV只能操作寄存器
LDR和STR是把数据从内存到寄存器之间操作
LSL左移
【R1】相当于C中*R1

寻址方式

1、立即数寻址
ADD R0,R0#0X3F (把R0自己加3F在给R0就是地址)
2、寄存器寻址
ADD R0,R1,R2(R1加R2再把值给R0)
3、寄存器间接寻址
LDR R0,[R1](把R1里所指向的内存地址的值给R0,如R1里为0xffff,认为他是一个内存的地址,将这个地址里的值赋给R0)
STR R0,[R1] (把R0的值放到R1中的内存地址)
4、寄存器移位寻址
ADD R3,R2,R1,LSL #2(R1左移两位加R2赋给R3)
5、基址地址寻址
LDR R0,[R1,#4](将R1的值加4的地址的值给R0,地址+4)
LDR R0,[R1],#4(把R1的地址的值加4给R0)
LDR R0,[R1,R2] (R1的值加R2的值所指向的内存的值给R0)
6、多寄存器寻址
LDMIA R0,{R1,R2,R3,R4}
7、相对寻址
BL NEXT 跳转到NEXT,并且把状态保存到某个寄存器相当于C中的go to
MOV PC,LR 子程序返回

ARM堆栈
满堆栈 堆栈指针指向最上面的地址时为满堆栈
空堆栈
递增堆栈 栈由低地址向高地址堆
递减堆栈 由高地址向低地址堆
在LDR和STR时要考虑堆栈,

汇编算术(逻辑)操作

数学操作

在这里插入图片描述
ADDS加法运算时会影响状态位

逻辑运算
与或非异或
在这里插入图片描述
比较操作
在这里插入图片描述
TEQ是异或操作。相等的话0标志位会为·1

汇编内存操作

LDR Rn,地址 内存中的数据读取到寄存器中,按照字长读取(32位字长word为4字节)
STR Rn,地址 把寄存器Rn中的数发送到内存地址

LDRB
STRB
同上,但是是按照字节操作。
LDRH STRH 半字长读写
LDRBT STRBT 用户模式下的按字读写
LDRT STRT 也是用户模式下的

LDRSB LDRSH 有符号字节加载,有符号半字长加载。有符号会影响到标志位
多寄存器内存访问指令
LDM【地址操作模式】 Rn(基址存储器)
LDMIA R1 {R2,R3,R4} 把R1地址的数据拿出来给R2.R3.R4每取一次地址加4
STM
地址模式:
数据块模式:IA(传输后地址加4),IB(传送前地址加4),DA(传送后地址减4),DB(传送前地址减4)
堆栈模式:,EA(空递减堆栈)FD(满递减堆栈),ED(空递增堆栈),FA(满递增堆栈)

数据交换治疗
SWP Rd,Rn1,[Rn2] 内存和寄存器字交换
SWPB 字节交换
把内存Rn2中 的数据取出来放到Rd,然后把R1的值放到R2中 rd相当于中间寄存器
如果Rd和R1是直接寄存器就是直接交换。实际工程中都是写成一样的,
如SWP R1,R1,[R2]

spsr cpsr 状态寄存器 都不可以操作,一般用到pc

跳转指令

mov lr pc
mov pc XXXX
把当前的程序连接放到lr中暂存,然后第二个指令会使程序跳转。一会还可以在lr取回跳转前状态。但是lr保存的要加4,因为一个指令是32位,回来的时候要进到下一个指令了
B 标签(lable) 跳转到
BL带返回的连接跳转
BX 跳转并切换状态thumb
BLX待返回的跳转并切换状态thumb
状态寄存器操作:把32位指令分为了4个域:【7:0】控制位域c,【15:8】扩展位域X
【23:16】状态位域s【31;24】条件标志位域f
MRS Rn CPSR/SPSR 把程序状态寄存器的值传送到通用寄存器
MSR CPSR/SPSR Rn 通用寄存器到程序状态寄存器

CPSR_c 用下划线可以指定域。

异常产生治疗

异常是一种特殊的软中断
SWI +中断号 软中断指令
BKPT 断点中断指令

ARM汇编伪指令

伪指令类似C中的宏
常见的有ARM汇编伪指令和GNU汇编伪指令
比如开头的ENTRY就是伪指令

基本常用伪指令
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在汇编语言程序中常用的符号
符号命名约定:
符号区分大小写,同名的大小写符号会被编译器认为是两个不同的符号
符号在其作用范围内必须唯一
自定义的符号名不能与系统的保留字相同
符号名不应与指令或伪指令同名
注意顶行或者加TAB
在这里插入图片描述
A数字变量L逻辑变量S字符串变量
RUST给一个寄存器列表定义一堆寄存器的别名
常量
比如 LD R0 ,=0x12用等号定义常量
数字常量一般为32位的整数。当作为无符号数时。其取值范围为0到2的31次方。当作为有符号数时,其取值范围为-2的三十一次方到2的三十次方
逻辑常量只有两种情况:真或假
字符串常量为一个固定的字符串,一般用于程序运行时的消息提示

变量代换$
程序中的变量可通过代换操作区的一个常量。代换操作符为”$“
例子:
LCLS S1
LCLS S2
S1 SETS “Test!”
S2 SETS ”this is a $S1“
S2为”this is a Test“

表达式和运算符
加减× /及mod算术运算符
ROL ROR SHL SHR 移位运算符
AND OR NOT EOR 按位逻辑运算符

= < > >= <= /= <>
LAND LOR LNOT LEOR 整体逻辑运算

寄存器操作
LDR 某时候可以替代MOV MVN 大范围寻址到寄存器 绝对寻址
如果后面是个立即数,可以直接操纵
ADR 小范围寻址到寄存器 255的区间,相对寻址
ADRL 中范围寻址寄存器 -相对寻址

数据定义
在这里插入图片描述

控制伪指令
在这里插入图片描述
IF ELSE前要有TAB
宏定义有点类似函数
MACRO
$OP hello $paran1
mov R3,0x02
MEND
OP hello 参数1

混合编程

汇编语言与C/C++的混合编程通常有3种方式
在C/C++代码中嵌入汇编指令
汇编调用C/C++
C/C++调用汇编

1、c语言嵌入汇编
格式:__asm 后面为可选选项:【volatile】【instruction】(如volatile就是不使用优化)
{

}
限制条件
不能直接向PC寄存器赋值。程序跳转要使用B或BL指令
在使用物理寄存器时,如要使用过于复杂的C表达式,避免物理寄存器冲突;
R12和R13可能被编译器用存不放中间编译结果,计算表达式值时可能把R0-R3、R12及R4用于子程序调用,因此避免直接使用这些物理寄存器。
一般就使用R0到R7寄存器
在这里插入图片描述

2、在C语言中调用汇编
1、汇编export
2、C语言定义extern function
3、C语言使用
C语言和汇编语言之间的参数传递是通过对应的用R0-R3来进行传递。即R0传递第一个参数,R1传递第二个参数,多于4个时,借助栈来完成。函数的返回值通过R0来传递。这个规定叫做ATPCS。

在这里插入图片描述

3、汇编调用C语言
1、C语言实现函数
2、汇编import函数名
3、BL函数名
C语言和汇编语言之间的参数传递是通过对应的用R0-R3来进行传递。即R0传递第一个参数,R1传递第二个参数,多于4个时,借助栈来完成。函数的返回值通过R0来传递。
在这里插入图片描述
在这里插入图片描述

发布了33 篇原创文章 · 获赞 4 · 访问量 2606

猜你喜欢

转载自blog.csdn.net/CNMNMSL1/article/details/105075970