解决方案

ARM系统简介

seo靠我 2023-09-25 08:38:22

ARM系统学习笔记

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

ARM系统简介

1.1 ARM工作模式

ARM有两种工SEO靠我作状态:

第一种为ARM状态,此时处理器执行32位的字对齐的ARM指令

第二种为Thumb状态,此时处理器执行16位、半字节对齐的Thumb指令

ARM支持7种工作模式:

1、用户模式(usr)(10000)SEO靠我:

正常执行程序

2、快速中断模式(FIQ)(10001):

高速数据传输

3、外部中断模式(IRQ)(10010):

普通中断处理

4、管理模式(svc)(10011)

操作系统使用的保护模式

5、数据访问终止模式SEO靠我(abt)(10111):

用于虚拟存储和存储保护

6、系统模式(sys)(11111):

用于运行特权级的操作系统任务

7、未定义指令中止模式(und)(11011):

用于支持通过软件仿真硬件的协处理器

1.SEO靠我2 ARM寄存器

ARM微处理器共有37个寄存器,其中31个通用寄存器,6个状态寄存器。寄存器无法同时被访问,具体可以访问哪些寄存器取决于ARM处理器工作状态及具体的运行模式。

不分组寄存器:R0~R7

SEO靠我组寄存器:R8~R14

1、R13通常用作堆栈指针SP

2、R14用作子程序链接寄存器(Link Register-LR)指向函数的返回地址

程序寄存器:R15(PC指针(程序运行的位置))

状态寄存器CPSSEO靠我R/SPSR各位表示的信息:

1.3 ARM寻址方式

寻址方式根据指令中给出的地址来寻找物理地址的方式。

立即寻址也叫立即数寻址,直接给定具体数字;

寄存器寻址是查找寄存器里的值来寻找;

寄存器间接寻找(寄存器SEO靠我里的值是地址);

基地变址寻址,给出的地址进行偏移从而得到有效地址;

多寄存器寻址,一次访问多个寄存器

相对寻址,与基地变址寻址相似,比如进入子程序,在主程序上进行偏移

堆栈寻址,先进后出寻址。

1.4 ARMSEO靠我 指令集

1.4.1 跳转指令

B 跳转指令

B{条件} 目的地址 #{}表示条件可以有也可以没有。

B Label #程序直接跳转到label

BEQ Label #当CPSR寄存器中的Z条件码置位时,程序跳SEO靠我转到label

条件包括下面这些条件:

BL 带返回的跳转指令

BL{条件} 目标地址

BL 在跳转之前,会在寄存器R14中保存PC当前值。通过将R14的内容重新加载到PC,来返回到跳转指令之后的那个指令执行SEO靠我。一般实现子函数的调用

example:BL Label

BLX 带返回和状态切换的跳转指令

BLX{条件} 目标地址,指令跳转到目标地址并将处理器的工作状态由ARM状态切换为Thumb状态,同将PC的当前SEO靠我内容保存到寄存器R14中。因此,当子程序使用thumb指令集,可以通过此指令。

BX 带状态切换的跳转指令

BX{条件} 目标地址

1.4.2 数据处理指令

MOV指令

MOV{条件}{s} 目的寄存器,源操作SEO靠我

example:

MOV R1,R0 ;将寄存器R0传到R1

MVN指令

MVN{条件}{s} 目的寄存器,源操作数 #与mov指令的不同之处在于传送之前按位被取反,即把一个被取反的值传送到寄存器中,例MSEO靠我VN R0,#0xff; R0<=0xffffff00

CMP比较指令

CMP{条件} 操作数1,操作数2 # 比较完之后,会更新CPSR中条件标志位的值,该指令执行一次减法运算,不存储结果,只更改条件标SEO靠我志位

TST指令,将一个寄存器的内容与另一个寄存器或是立即数按位与的运算,将结果更新到CPSR中,结果为0则EQ位被设置

TST{条件} 操作数1,操作数2;例如: TST R1, # %1;用于测试R1SEO靠我中最低位是否为1

ADD指令-相加

ADD{条件}{s} 目的寄存器,操作数1,操作数2

ADD R0,R2,R3,LSL#1; # R0 = R2 + (R3<<1)

SUB指令-相减

SUB{条件}{s} SEO靠我目的寄存器,操作数1,操作数2

SUB R0,R2,R3,LSL#1; # R0 = R2 - (R3<<1)

AND指令-两个操作数进行逻辑与

AND{条件}{s} 目的寄存器,操作数1,操作数2

AND SEO靠我R0, R0,#3;保持R0的0、1位,其余位清零 R0 = R0 & 3;

ORR指令-两个操作数进行逻辑或

ORR{条件}{s} 目的寄存器,操作数1,操作数2

ORR R0, R0,#3;R0的0、1SEO靠我位清零,其他位不变 R0 = R0 | 3;

BIC指令

BIC{cond}{s} Rd,Rn,操作数2 #清楚Rn中的某些位,结果存放在Rd中。

BIC R0, R0,#%1011;R0的0、1、3位清零SEO靠我,其他位不变

MUL指令-乘法

MUL{条件}{s} 目的寄存器,操作数1,操作数2

MUL R0,R1,R2;# R0 = R1 * R2

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

MRS 指令

MRS{条件} 通用SEO靠我寄存器,程序状态寄存器(CPSR或SPSR)

该指令用于将程序状态寄存器的内容传送到通用寄存器,原因是程序状态寄存器没办法直接操作

MRS R0,CPSR;将CPSR状态传递到R0中

MSR 指令

MSR{条SEO靠我件} 程序状态寄存器_<域>(CPSR或SPSR), 通用寄存器

该指令与MRS相反,将操作数的内容传送到程序状态寄存器的特定域中。

位[31:24]为条件标志域,用f表示;位[23:16]为状态域,用表SEO靠我

位[15:8]为扩展位域,用x表示;位 [7:0]位控制位域,用c表示

MSR CPSR,R0;将R0的内容传递给CPSR

MSR CPSR_c,R0;传送R0的内容到SPSR,但仅仅修改CPSR中的cSEO靠我控制位域

1.4.4 加载/存储指令

LDR 指令

LDR{条件} 目的寄存器,<存储器地址>

用于从存储器中将一个32位的字数据传送到目的寄存器中,读取32位的字数据到通用寄存器中

LDR R0,[R1];将SEO靠我存储器地址为R1的字数据读入寄存器R0

LDR R0,[R1, R2];将地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2存到R1中

LDRB 指令

LDRB{条件} 目的寄存器,<存储器地址>SEO靠我

同LDR,只是这个只取字节数据的低8位,高24位清零

LDRH 指令

LDRH{条件} 目的寄存器,<存储器地址>

同LDR,只是这个只取字节数据的低16位,高16位清零

STR 指令

STR{条件} 源寄存器SEO靠我,<存储器地址>

用于从源寄存器中将32位的字数据传送到存储器地址中

STR R0, [R1], #8;将R0中的字数据写入到R1为地址的存储器中,并将新地址R1+8写入R1

STR R0,[R1, #8]SEO靠我;将R0中的字数据写入到以R1+8位地址的存储器中

1.4.5 批量加载/存储指令

LDM 批量数据加载指令

LDM{条件}{类型} 基址寄存器{!},寄存器列表{^}

从由基址寄存器所指示的一片连续存储器到SEO靠我寄存器列表所指示的多个寄存器之间的传送数据

STM 批量数据存储指令

STM{条件}{类型} 基址寄存器{!},寄存器列表{^}

STMFD R13!,{R0,R4-R12, LR};将寄存器列表中的寄存器SEO靠我R0,R4到R12,LR存储到R13寄存器所指的内存地址中去(堆栈)

LDMFD R13!,{R0,R4-R12, LR};将堆栈内容恢复到寄存器R0,R4到R12,LR中

其中,{类型}有以下几种情况:SEO靠我

IA 每次传送后地址加1

IB 每次传送前地址加1

DA 每次传送后地址减1

DB 每次传送前地址减1

FD 满递减堆栈

ED 空递减堆栈

FA 满递增堆栈

EA 空递增堆栈

{!}{^}为可选后缀

1.4.6 数据交SEO靠我换指令

SWP 字数据交换指令

SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]

将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指的存储器中

SWPSEO靠我 R0, R1,[R2]; 将R2所指向的存储器中的字数据传送到R0,同时将R1中的字数据传送到R2所指向的存储器单元

SWP R0,R0,[R1];R1所指向的存储器中的字数据与R0中的字数据交换

SWSEO靠我PB 字节数据交换指令

1.4.7 移位指令

LSL 左移位指令

通用寄存器,LSL操作数

MOV R0,R1,LSL#2;将R1中的内容左移两位后传送到R0中

ROR 循环右移

MOV R0,R1,ROR#2;SEO靠我将R1中的内容循环右移两位后传送到R0中

1.5 ARM伪指令

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

SEO靠我号定义伪指令

用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。常见的有 定义全局变量的GBLA、GBLL和GBLS定义局部变量的LCLA、LCLL和LCLSSEO靠我对变量赋值的SETA、SETL、SETS为通用寄存器列表定义名称的RLIST

GBLA test1

定义一个全局数字变量,变量名为test1

test1 SETA 0xaa

将变量赋值为0xaa

GBLL teSEO靠我st2

定义一个全局逻辑变量

test2 SETL {TRUE}

赋值为真

GBLS test3

定义一个全局字符串变量,变量名为test3

test3 SETS “testing”

RegList RLIST {SEO靠我R0-R5,R8,R10};将寄存器列表名称定义为RegList 数据定义伪指令

标号 DCB 表达式

分配一片连续的字节存储单元并按指定的表达式初始化

Str DCB “this SEO靠我is a test“;分配一片连续的字节存储单元并初始化,Str只是取的别名

标号 SPACE 表达式

DataSpace SPACE 100;分配连续的100字节的存储单元并初始化为0;

MAP 表达式 SEO靠我{基址寄存器}

MAP 0x100,R0;定义内存表首地址是R0+0x100

标号 FIELD 表达式

MAP 0x100;定义结构化内存表首地址为0x100

A FIELD 16;定义A的长度为16字节,地SEO靠我址为0x100

B FIELD 32;定义B的长度为32字节,地址为0x110汇编控制伪指令

GBLL test;声明一个逻辑变量

IF test = TRUE

指令序列1

ELSE

指令序列2

ENDIF

WHILSEO靠我E 逻辑表达式

指令序列

WEND

1.6 c/c++/汇编混合编程

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

在c/c++程序中嵌入汇编指令在汇编程序中访问c/c++定义的全局变量在c/c++程序中调用汇编函数SEO靠我汇编程序中调用c/c++函数 在c/c++程序中嵌入汇编指令格式如下:

__asm

{

汇编程序

}在汇编程序中访问c/c++定义的全局变量,格式如下:

int gVar = 12;

汇编SEO靠我文件:

IMPORT gVar在c/c++程序中调用汇编函数,一是在c中声明函数原型,并加extern关键字,二是在汇编中用EXPORT导出,格式如下

汇编文件:

EXPORT asm_strcpy

asm_SEO靠我strcpy

loop:

END

c文件中:

extern void asm_strcpy(const char*s, const char * d);汇编程序中调用c/c++函数,格式如下:

c文件中定义函SEO靠我数cfun()

汇编文件:

IMPORT cfun

ENTRY

BL cfun #跳转到cfun

END
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2