【ARM汇编速成】零基础入门汇编语言之指令集(二)

简介: 【ARM汇编速成】零基础入门汇编语言之指令集(二)

三.ARM指令集

1.指令格式

ARM采用三地址指令格式:

<opcode>   {<cond>}   {S}   <Rd>,<Rn>{,<operand2>}

其中<>内容为必须的,{}为可选的。

<opcode>:操作码,代表指令执行的操作类型,如加法(ADD)、减法(SUB)、移动(MOV)等。


{<cond>}:条件码,是可选的,用于指定指令执行的条件,如等于(EQ)、不等于(NE)、无符号大于(HI)等。条件码允许指令在满足特定条件时才执行。


{S}:标志位,是可选的,如果存在,表示指令执行后会影响CPSR(当前程序状态寄存器)的条件标志位(如N、Z、C、V)。


<Rd>:目标寄存器,指令执行结果的存放位置。


<Rn>:第一个操作数寄存器,通常包含源操作数。


{,<operand2>}:第二个操作数,是可选的,可以是立即数(一个常数)、寄存器或者寄存器加上一个偏移量。如果存在,它必须用逗号与<Rn>隔开。


提示:汇编中的注释符为';'。

2.寻址方式

即处理器根据指令信息找到操作数的方式:


1、立即数寻址( 操作数直接在指令中 mov R1,#3:将3放到R0)


立即数被表示为#immed_8,即常数表达式。


2、寄存器寻址


mov R0,R1:将R0的值放到R1中


操作数即为寄存器的数值。

3、寄存器间接寻址


mov R0,[R2]:将R2中的值为地址指向内存中的数放到R0中


操作数在寄存器值为地址指向的内存中


4、寄存器位移寻址


mov R0,R1,lsl#3:将R1中值左移3位放到R0中


当第二个数为位移方式时、将寄存器的值先位移处理得到操作数


5、寄存器基址寻址(也叫基址变址寻址)


LDR R0, [R1,   #4]:先将R1中的值加4 然后以结果为地址 对应的内存操作数放到R0


由间接寻址发展而来,先对寄存器中的值进行计算,再以结果为地址,取其指向内存值为操作数。


6、多寄存器寻址

STMIA R0!,{R2-R7,R12}:将 R2 到 R7 和 R12 放到 R0 指向的地址中


 一条指令传送多个(最多16个)寄存器值


7、相对寻址


BL NEXT:跳转到NEXT标签处


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


8、拷贝寻址。将连续的寄存器值进行操作。


       STMIA R0! ,{R1-R7}:将R1~R7的数据保存到R0指向的地址中


9、堆栈寻址。将栈用于操作数保存或者导出的操作。


       STMFD SP!,{R1-R7,LR}:将R1~R7,LR入栈,SP更新。满递减堆栈

3.伪指令

       汇编器定义了一些特殊的指令助记符,即伪指令(也叫做伪操作),它们就类似于C语言中的预处理命令,是为了方便对汇编程序做各种处理而生的。伪指令用于指导汇编器在汇编过程中执行特定的任务,如数据定义、内存分配、段定义等,它们在汇编程序转换成机器代码的过程中被处理,但在生成的机器代码中并不直接体现。


/******************** 基础伪操作 ********************/

ALIGN   ;地址对齐

AREA  ;用来定义一个代码段或数据段,常用的段属性为CODE/DATA

ENTRY  ;指定汇编程序的执行入口

END   ;用来告诉编译器源程序已到了结尾,停止编译

EQU   ;赋值伪指令,类似宏,给常量定义一个符号名

 

CODE16/CODE32  ;指示编译器后面的指令为THUMB/ARM 指令

EXPORT/GLOBAL  ;声明一个全局符号,可以被其他文件引用

IMPORT/EXTERN  ;引用其他文件的全局符号前,要先IMPORT

GET/INCLUDE   ;包含文件,并将该文件当前位置进行编译,一般包含的是程序文件

INCBIN    ;包含文件,但不编译,一般包含的是数据、配置文件等

 

/******************** 变量定义 ********************/

//全局变量定义

GBLA a    ;定义一个全局算术变量a,并初始化为0

a SETA 10   ;给算术变量a赋值为10

GBLL b    ;定义一个全局逻辑变量b,并初始化为false

b SETL 20   ;给逻辑变量b赋值为20

GBLS STR   ;定义一个全局字符串变量STR,并初始化为0

STR SETS "123"  ;给变量STR赋值为"123"

//局部变量定义

LCLA a    ;定义一个局部算术变量a,并初始化为0

LCLL b    ;定义一个局部逻辑变量b,并初始化为false

LCLS name   ;定义一个局部字符串变量name,并初始化为0

name SETS "123"  ;给局部字符串变量赋值

 

/******************** 数据定义 ********************/

DATA1 DCB 10,20,30,40 ;分配一片连续的字节存储单元名为DATA1,并初始化

STR DCB "123"   ;给字符串STR分配一片连续的存储单元并初始化

DATA2 DCD 10,20,30,40 ;分配一片连续的字存储单元名为DATA2,并初始化

BUF SPACE 100   ;给BUF分配100字节的存储单元并初始化为0

DATA 10,20,30,40  ;定义了一个包含四个整数的数据集合

举例,下面我们实现了一个汇编子程序SUM_ASM,使用EXPORT伪操作将其声明为一个全局符号(这样其他汇编程序或C程序就可以直接调用它了),SUM_ASM自身又调用了其他子程序sum(这个sum子程序可以是一个汇编子程序,也可以是一个使用C语言定义的函数),在调用之前我们要先使用IMPORT伪操作把sum子程序导入进来,然后就可以直接使用BL指令跳转过去运行了。


IMPORT sum

AREA SUM_ASM,CODE,READONLY

EXPORT SUM_ASM

SUM_ASM

STR LR, [SP, #-4]  ;保存调用者的返回地址

LDR R0, =0X3   ;参数传递

LDR R1, =0X4   ;参数传递

BL sum     ;调用其他文件里的子程序

LDR PC, [SP], #4  ;返回主程序,继续运行


相关文章
|
2月前
|
存储 编译器 C语言
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
|
2月前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
7月前
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
277 2
|
7月前
|
存储 机器学习/深度学习 移动开发
汇编语言指令系列
汇编语言指令系列
905 0
几组汇编指令的比较
几组汇编指令的比较
|
5月前
|
存储 机器学习/深度学习 芯片
8086 汇编笔记(十二):int 指令 & 端口 & 直接定址表
8086 汇编笔记(十二):int 指令 & 端口 & 直接定址表
|
5月前
|
存储 算法 安全
深入理解汇编语言:基础语法和常用指令介绍
深入理解汇编语言:基础语法和常用指令介绍
|
6月前
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
103 1
8086 汇编笔记(九):call 指令 和 ret 指令
8086 汇编笔记(九):call 指令 和 ret 指令
|
5月前
|
编译器
8086 汇编笔记(八):转移指令的原理
8086 汇编笔记(八):转移指令的原理

热门文章

最新文章

下一篇
DataWorks