首页 > 编程知识 正文

arm系统设计,arm架构的系统

时间:2023-05-04 18:16:01 阅读:207098 作者:4647

ARM系统学习笔记 ARM系统简介1.1 ARM工作模式1.2 ARM寄存器1.3 ARM寻址方式1.4 ARM 指令集1.4.1 跳转指令1.4.2 数据处理指令1.4.3 程序状态寄存器访问指令1.4.4 加载/存储指令1.4.5 批量加载/存储指令1.4.6 数据交换指令1.4.7 移位指令 1.5 ARM伪指令1.6 c/c++/汇编混合编程

ARM系统简介 1.1 ARM工作模式

ARM有两种工作状态:
第一种为ARM状态,此时处理器执行32位的字对齐的ARM指令
第二种为Thumb状态,此时处理器执行16位、半字节对齐的Thumb指令

ARM支持7种工作模式:
1、用户模式(usr)(10000):
正常执行程序
2、快速中断模式(FIQ)(10001):
高速数据传输
3、外部中断模式(IRQ)(10010):
普通中断处理
4、管理模式(svc)(10011)
操作系统使用的保护模式
5、数据访问终止模式(abt)(10111):
用于虚拟存储和存储保护
6、系统模式(sys)(11111):
用于运行特权级的操作系统任务
7、未定义指令中止模式(und)(11011):
用于支持通过软件仿真硬件的协处理器

1.2 ARM寄存器

ARM微处理器共有37个寄存器,其中31个通用寄存器,6个状态寄存器。寄存器无法同时被访问,具体可以访问哪些寄存器取决于ARM处理器工作状态及具体的运行模式。
不分组寄存器:R0~R7
分组寄存器:R8~R14
1、R13通常用作堆栈指针SP
2、R14用作子程序链接寄存器(Link Register-LR)指向函数的返回地址
程序寄存器:R15(PC指针(程序运行的位置))
状态寄存器CPSR/SPSR各位表示的信息:

1.3 ARM寻址方式

寻址方式根据指令中给出的地址来寻找物理地址的方式。
立即寻址也叫立即数寻址,直接给定具体数字;
寄存器寻址是查找寄存器里的值来寻找;
寄存器间接寻找(寄存器里的值是地址);
基地变址寻址,给出的地址进行偏移从而得到有效地址;
多寄存器寻址,一次访问多个寄存器
相对寻址,与基地变址寻址相似,比如进入子程序,在主程序上进行偏移
堆栈寻址,先进后出寻址。

1.4 ARM 指令集 1.4.1 跳转指令

B 跳转指令
B{条件} 目的地址 #{}表示条件可以有也可以没有。
B Label #程序直接跳转到label
BEQ Label #当CPSR寄存器中的Z条件码置位时,程序跳转到label
条件包括下面这些条件:

BL 带返回的跳转指令
BL{条件} 目标地址
BL 在跳转之前,会在寄存器R14中保存PC当前值。通过将R14的内容重新加载到PC,来返回到跳转指令之后的那个指令执行。一般实现子函数的调用
example:BL Label
BLX 带返回和状态切换的跳转指令
BLX{条件} 目标地址,指令跳转到目标地址并将处理器的工作状态由ARM状态切换为Thumb状态,同将PC的当前内容保存到寄存器R14中。因此,当子程序使用thumb指令集,可以通过此指令。
BX 带状态切换的跳转指令
BX{条件} 目标地址

1.4.2 数据处理指令

MOV指令
MOV{条件}{s} 目的寄存器,源操作数
example:
MOV R1,R0 ;将寄存器R0传到R1
MVN指令
MVN{条件}{s} 目的寄存器,源操作数 #与mov指令的不同之处在于传送之前按位被取反,即把一个被取反的值传送到寄存器中,例MVN R0,#0xff; R0<=0xffffff00
CMP比较指令
CMP{条件} 操作数1,操作数2 # 比较完之后,会更新CPSR中条件标志位的值,该指令执行一次减法运算,不存储结果,只更改条件标志位
TST指令,将一个寄存器的内容与另一个寄存器或是立即数按位与的运算,将结果更新到CPSR中,结果为0则EQ位被设置
TST{条件} 操作数1,操作数2;例如: TST R1, # %1;用于测试R1中最低位是否为1
ADD指令-相加
ADD{条件}{s} 目的寄存器,操作数1,操作数2
ADD R0,R2,R3,LSL#1; # R0 = R2 + (R3<<1)
SUB指令-相减
SUB{条件}{s} 目的寄存器,操作数1,操作数2
SUB R0,R2,R3,LSL#1; # R0 = R2 - (R3<<1)
AND指令-两个操作数进行逻辑与
AND{条件}{s} 目的寄存器,操作数1,操作数2
AND R0, R0,#3;保持R0的0、1位,其余位清零 R0 = R0 & 3;
ORR指令-两个操作数进行逻辑或
ORR{条件}{s} 目的寄存器,操作数1,操作数2
ORR R0, R0,#3;R0的0、1位清零,其他位不变 R0 = R0 | 3;
BIC指令
BIC{cond}{s} Rd,Rn,操作数2 #清楚Rn中的某些位,结果存放在Rd中。
BIC R0, R0,#%1011;R0的0、1、3位清零,其他位不变
MUL指令-乘法
MUL{条件}{s} 目的寄存器,操作数1,操作数2
MUL R0,R1,R2;# R0 = R1 * R2

1.4.3 程序状态寄存器访问指令

MRS 指令
MRS{条件} 通用寄存器,程序状态寄存器(CPSR或SPSR)
该指令用于将程序状态寄存器的内容传送到通用寄存器,原因是程序状态寄存器没办法直接操作
MRS R0,CPSR;将CPSR状态传递到R0中
MSR 指令
MSR{条件} 程序状态寄存器_<域>(CPSR或SPSR), 通用寄存器
该指令与MRS相反,将操作数的内容传送到程序状态寄存器的特定域中。
位[31:24]为条件标志域,用f表示;位[23:16]为状态域,用表示
位[15:8]为扩展位域,用x表示;位 [7:0]位控制位域,用c表示
MSR CPSR,R0;将R0的内容传递给CPSR
MSR CPSR_c,R0;传送R0的内容到SPSR,但仅仅修改CPSR中的c控制位域

1.4.4 加载/存储指令

LDR 指令
LDR{条件} 目的寄存器,<存储器地址>
用于从存储器中将一个32位的字数据传送到目的寄存器中,读取32位的字数据到通用寄存器中
LDR R0,[R1];将存储器地址为R1的字数据读入寄存器R0
LDR R0,[R1, R2];将地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2存到R1中
LDRB 指令
LDRB{条件} 目的寄存器,<存储器地址>
同LDR,只是这个只取字节数据的低8位,高24位清零
LDRH 指令
LDRH{条件} 目的寄存器,<存储器地址>
同LDR,只是这个只取字节数据的低16位,高16位清零
STR 指令
STR{条件} 源寄存器,<存储器地址>
用于从源寄存器中将32位的字数据传送到存储器地址中
STR R0, [R1], #8;将R0中的字数据写入到R1为地址的存储器中,并将新地址R1+8写入R1
STR R0,[R1, #8];将R0中的字数据写入到以R1+8位地址的存储器中

1.4.5 批量加载/存储指令

LDM 批量数据加载指令
LDM{条件}{类型} 基址寄存器{!},寄存器列表{^}
从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间的传送数据
STM 批量数据存储指令
STM{条件}{类型} 基址寄存器{!},寄存器列表{^}
STMFD R13!,{R0,R4-R12, LR};将寄存器列表中的寄存器R0,R4到R12,LR存储到R13寄存器所指的内存地址中去(堆栈)
LDMFD R13!,{R0,R4-R12, LR};将堆栈内容恢复到寄存器R0,R4到R12,LR中
其中,{类型}有以下几种情况:
IA 每次传送后地址加1
IB 每次传送前地址加1
DA 每次传送后地址减1
DB 每次传送前地址减1
FD 满递减堆栈
ED 空递减堆栈
FA 满递增堆栈
EA 空递增堆栈
{!}{^}为可选后缀

1.4.6 数据交换指令

SWP 字数据交换指令
SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]
将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指的存储器中
SWP R0, R1,[R2]; 将R2所指向的存储器中的字数据传送到R0,同时将R1中的字数据传送到R2所指向的存储器单元
SWP R0,R0,[R1];R1所指向的存储器中的字数据与R0中的字数据交换
SWPB 字节数据交换指令

1.4.7 移位指令

LSL 左移位指令
通用寄存器,LSL操作数
MOV R0,R1,LSL#2;将R1中的内容左移两位后传送到R0中
ROR 循环右移
MOV R0,R1,ROR#2;将R1中的内容循环右移两位后传送到R0中

1.5 ARM伪指令

在ARM汇编语言程序里,有一些特殊的指令助记符,称为伪指令,作用是为了完成汇编程序做各种准备工作,仅在汇编过程中起作用。主要分为以下几类:

符号定义伪指令
用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。常见的有 定义全局变量的GBLA、GBLL和GBLS定义局部变量的LCLA、LCLL和LCLS对变量赋值的SETA、SETL、SETS为通用寄存器列表定义名称的RLIST
GBLA test1
定义一个全局数字变量,变量名为test1
test1 SETA 0xaa
将变量赋值为0xaa
GBLL test2
定义一个全局逻辑变量
test2 SETL {TRUE}
赋值为真
GBLS test3
定义一个全局字符串变量,变量名为test3
test3 SETS “testing”
RegList RLIST {R0-R5,R8,R10};将寄存器列表名称定义为RegList 数据定义伪指令
标号 DCB 表达式
分配一片连续的字节存储单元并按指定的表达式初始化
Str DCB “this is a test“;分配一片连续的字节存储单元并初始化,Str只是取的别名
标号 SPACE 表达式
DataSpace SPACE 100;分配连续的100字节的存储单元并初始化为0;
MAP 表达式 {基址寄存器}
MAP 0x100,R0;定义内存表首地址是R0+0x100
标号 FIELD 表达式
MAP 0x100;定义结构化内存表首地址为0x100
A FIELD 16;定义A的长度为16字节,地址为0x100
B FIELD 32;定义B的长度为32字节,地址为0x110汇编控制伪指令
GBLL test;声明一个逻辑变量
IF test = TRUE
指令序列1
ELSE
指令序列2
ENDIF
WHILE 逻辑表达式
指令序列
WEND 1.6 c/c++/汇编混合编程

汇编语言与c/c++的混合方式主要有:

在c/c++程序中嵌入汇编指令在汇编程序中访问c/c++定义的全局变量在c/c++程序中调用汇编函数汇编程序中调用c/c++函数 在c/c++程序中嵌入汇编指令格式如下:
__asm
{
汇编程序
}在汇编程序中访问c/c++定义的全局变量,格式如下:
int gVar = 12;
汇编文件:
IMPORT gVar在c/c++程序中调用汇编函数,一是在c中声明函数原型,并加extern关键字,二是在汇编中用EXPORT导出,格式如下
汇编文件:
EXPORT asm_strcpy
asm_strcpy
loop:

END
c文件中:
extern void asm_strcpy(const char*s, const char * d);汇编程序中调用c/c++函数,格式如下:
c文件中定义函数cfun()
汇编文件:
IMPORT cfun
ENTRY

BL cfun #跳转到cfun
END

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。