一、简单汇编指令介绍
1.1、.file
告诉汇编器当前正在汇编的文件的名称
1.2、.syntax unified
指定汇编器的语法格式,指定为使用同统一语法(ARM汇编中有传统语法和统一语法两种格式)
1.3、.cpu
指定目标处理器的架构类型(指定处理器的型号和特性),常见的有X86,ARM,RISC-V等
1.4、.arch
指定目标处理器的架构类型和主要特性
1.5、.fpu
指定浮点运算单元(FPU)的类型和特性,后面跟的示例如下:
softvfp:软件浮点运算,不使用硬件 FPU。
vfpv3:使用 ARMv7 架构中的 VFPv3 浮点运算单元。
vfpv4:使用 ARMv7 架构中的 VFPv4 浮点运算单元。
fpv4-sp-d16:使用 ARMv7-M 架构中的 FPv4-SP-D16 浮点运算单元。
fp-armv8:使用 ARMv8 架构中的浮点运算单元。
1.6、.thumb
指定使用 THUMB 指令集进行编译
1.7、.equ symbol, expression
用于定义符号常量或数值常量
1.8、.word
将一个32位的值存储在当前位置
1.9、.globl
声明一个符号为全局符号,示例如下
_start:
b Reset_Handler
_start是一个全局符号,使用b指令可以跳转到标号所在的位置,然后跳转到Reset_Handler执行
1.10、.section
指定汇编代码的段
1.11、.weak
声明一个符号为弱符号
1.12、.type
声明一个符号的类型,示例如下:
.type symbol, type
type取值如下:
%function:函数类型,表示符号是一个函数。
%object:对象类型,表示符号是一个对象。
%data:数据类型,表示符号是一个数据。
1.13、ldr
将数据从内存加载到寄存器中,示例如下:
ldr sp, =_estack
格式如下:
ldr Rd, =expression 将一个常量加载到寄存器
ldr Rd, [Rn, #offset] Rn寄存器的值是一个地址,这个地址加上偏移offset,然后将这个地址存放的数据赋值给Rd寄存器
ldr Rd, [Rn], #offset Rn寄存器的值是一个地址,这个地址对应的值赋值给Rd寄存器,然后Rn寄存器中的地址加上offset
ldr Rd, [Rn, Rm] Rn寄存器的值是一个地址,Rm寄存器的值是一个数字,将Rn存放的地址加上偏移Rm寄存器中的数字,然后将这个地址对应的数据赋值给Rd寄存器
1.14、CPSID I
用于关闭IRQ中断,并设置为IRQ禁止模式
1.15、str
将数据从寄存器存储到内存中,格式如下:
str Rd, [Rn, #offset] Rn寄存器中存储的是一个地址,这个地址加上offset的偏移,然后将Rd中存储的数据放入到偏移后的地址
str Rd, [Rn], #offset Rn寄存器是存放的一个地址,将Rd中的数据存储到Rn地址指向的位置,然后Rn寄存器中的地址增加偏移offset
str Rd, [Rn, Rm] Rn寄存器中存储的是一个地址,Rm寄存器中存储的是一个值,将Rd的值放到Rn存放的地址加上偏移所指向的位置
1.16、movs
将一个值移动到指定的寄存器,并根据移动后的结果设置标志位,格式如下:
movs Rd, #imm8 #imm8表示一个8位的立即数
movs Rd, Rm Rm、Rn、Rd表示寄存器的编号
movs Rd, Rn, lsl #shift shift表示一个位移量
movs Rd, Rn, lsr #shift
movs Rd, Rn, asr #shift
movs Rd, Rn, ror #shift
其中lsl,lsr,asr,ror意思如下:
lsl:逻辑左移
lsr:逻辑右移
asr:算数右移
ror:循环右移
算数右移符号位不变,其他和逻辑右移一样
循环右移:将右侧移出的位移到左侧
程序状态寄存器(CPSR/SPSR)中有四个标志位,针对整个处理器而不是单个寄存器的标志位,其中:
Z标志位:结果为0时被置为1,否则为0;
N标志位:结果为负数时被置为1,否则为0;
C标志位:结果发生了溢出时被置为1,否则为0;
V标志位:当结果发生了算术溢出时被置为1,否则为0。
使用movs命令后,根据移动后的结果设置这些标志位的值
1.17、blx
进行分支跳转,后面可以跟寄存器或地址。如果后面是寄存器,则跳转到寄存器里面所存储的地址;如果跟的是地址,则跳到后面这个地址指向的位置。
1.18、bl
分支跳转命令,跳转到对应的标签执行
1.19、cmp
比较两个寄存器的值或一个寄存器和一个立即数的值,并根据结果将Z标志位改变
1.20、ittt
执行条件代码块,格式如下:
ittt cond
instr1
instr2
...
instrN
cond为条件判断,给出一个示例如下:
ittt lo 结果不为0时执行所有指令块,为0时只执行第一条指令;lo指示上一条指令的执行结果
1.21、movlo
满足条件的情况下给寄存器赋值
1.22、strlo
满足条件时将数据存储到内存中,格式如下:
strlo Rd, [Rn, #offset]
满足lo条件码的情况下将Rd的数据存放到Rn存放的地址加上offset指向的位置。
1.23、blo
blo指令执行时,会检查Z标志位的值,为0则跳转,否则不跳转
1.24、bx
跳转指令,示例如下:
bx lr 跳转到链接器lr中存储的地址处执行代码
1.25、msr
将一个值移动到系统寄存器中,格式如下:
msr reg, val reg是系统寄存器
二、寄存器介绍
2.1、sp
栈顶寄存器
2.2、r系列
r0 到 r3 通常用于存储函数参数和返回值。
r4 到 r11 通常用于存储临时变量和中间结果。
r12 通常用于存储一些常量值。
r13 是堆栈指针寄存器,通常使用 sp 代替。
r14 是链接寄存器,通常用于存储函数调用的返回地址。
r15 是程序计数器寄存器,通常使用 pc 代替
2.3、msplim
系统寄存器,设置处理器的堆栈指针限制,放置堆栈溢出和内存泄漏