企业网站手机端太简洁,互联网外包公司,做门窗投标网站,秦皇岛做网站1.汇编指令
1.1汇编指令的基本格式
opcode{cond}{s} Rd , Rn , shifter_operand
功能码{条件码}{cpsr影响位} 目标寄存器 , 第一操作寄存器 , 第二操作数
注#xff1a;第一操作寄存器…1.汇编指令
1.1汇编指令的基本格式
opcode{cond}{s} Rd , Rn , shifter_operand
功能码{条件码}{cpsr影响位} 目标寄存器 , 第一操作寄存器 , 第二操作数
注第一操作寄存器只能是寄存器 不能写数值 第二操作数可以写寄存器名 也可以写#一个数值 汇编不区分大小写 操作数可以是一个寄存器也可以是一个立即数 立即数能够经过编码后保存到指令空间中直接当作指令一部分去执行的数据。一个32位指令空间中预留了12位空间保存当前操作数 可以通过某一个规则对操作数进行处理将处理后数值放在这12个空间中。所以处理完能够保存到12位空间中的数据就是立即数。通常通过循环右移看是否能得到一个0-255之间的数如果可以说明该数据就是立即数
1.2数据处理指令
1.2.1数据搬移指令
1.mov {条件码} Rd Sh
将操作数搬移到目标寄存器中
mov R1 , #0x1
MOV R2, R1
2.mvn {条件码} Rd Sh
将操作数按位取反后搬移到目标寄存器中
mvn R1 , #0x1
MVN R2, R1
3.通过伪指令实现非立即数的搬移ldr Rd 非立即数
ldr Rd 0x81
1.2.2数据移位指令
1.逻辑左移
lsl{cond} Rd , Rn , Sh~
将Rn左移Sh位存到Rd中
2.逻辑右移
lsr{cond} Rd , Rn , Sh~
将Rn右移Sh位存到Rd中
3.循环右移 ror{cond} Rd , Rn , Sh~ 将Rn循环右移Sh位存到Rd中 LSL R1 R2 #0x12 LSR R1 R2 #2 1.2.3位运算指令
1.与 与0清零与1不变
and {cond} Rd , Rn , Sh~
and R1, r2 , #(0x12)
将Rn与Sh进行与运算存于Rd
2.或有1为1 全0为0
orr {cond} Rd , Rn , Sh~
Orr r1, r2, #(0x12)
将Rn与Sh进行或运算存于Rd
3.异或 相同为0 不同为1
eor {cond} Rd , Rn , Sh~
Eor R2, R1, #(0x10)
将Rn与Sh进行异或运算存于Rd
4.按位取反01交换
mvn见搬移指令2
5按位清零指为1清为0
bic {cond} Rd , Rn , Sh~
将Rn与Sh取反进行与运算存于Rd
bic r1, r2, #(0x12) and r1, r2, #(~(0x12)) 1.2.4算术运算指令
1.加法指令
add{cond}{s} Rd, Rn,Sh~
Rd RnSh~
adc{cond}{s} Rd, Rn,Sh~
Rd RnSh~cpsr寄存器的c位
2.减法指令
sub {cond}{s} Rd, Rn,Sh~
Rd Rn-Sh~
sbc{cond}{s} Rd, Rn,Sh~
Rd Rn-Sh~-cpsr寄存器的c位
3.乘法指令
mul{cond}{s} Rd, Rn,Sh~
Rd Rn*Sh~ 注 {s}存在时运算加法进位和减法不借位时cpsr位置1
32位处理器进行64位数据运算时先低八位后高八位低位运算影响c位高位运算考虑c位 1.2.5比较指令
1.cmp Rn Sh
将Rn和Sh比较本质是将二者进行减法运算并将结果存到cpsr寄存器 的nzcv位通常和条件码一起使用 2.tst Rd #0x1N
判断第N位是否为0.
3.TEQ Rd sh
判断二者是否相等
只能影响到z位无法影响到cvn位 1.2.6跳转指令
1.b 标签
跳转到指定标签下跳转后LR寄存器不保存程序的返回地址
2.bl 标签
跳转到指定标签下跳转后LR寄存器保存程序的返回地址 可实现程序到循环执行操作 比如累乘和阶乘 1.2.7内存读写指令
类比c语言通过指针读写地址下内存中的数据
*unsigned int*0x12345678 数值
向内存中写
1.str Rd[目标地址]
将Rd中的四字节数据写入到目标地址对应的内存中
2.strh Rd[目标地址]
将Rd中的2字节数据写入到目标地址对应的内存中
3.strb Rd[目标地址]
将Rd中的1字节数据写入到目标地址对应的内存中
向内存中读
4.ldr Rd[目标地址]
从目标地址对应的内存中读取4字节数据保存到Rd中
5.ldrh Rd[目标地址]
从目标地址对应的内存中读取2字节数据保存到Rd中
6.ldrb Rd[目标地址]
从目标地址对应的内存中读取1字节数据保存到Rd中
此外还分前索引后索引和自动索引
前索引以基地址偏移后为首地址读写
str Rd[基地址 偏移量]
将Rd的数据写入到基地址偏移量为首地址到内存中
ldr Rd[基地址 偏移量]
从基地址偏移量为首地址到内存中读取数据保存到Rd中
后索引以基地址进行为首地址进行读写之后基地址在进行偏移
str Rd [基地址]偏移量
将目标寄存器到数据写入以基地址为首地址的内存中然后基地址增加偏移量
ldr Rd [基地址] 偏移量
从以基地址为首地址的内存中读取数据保存到目标寄存器中然后将基地址增加偏移量的大小
自动索引以基地址偏移后为首地址进行读写同时基地址也进行自增自减
str Rd [基地址偏移量]
将基地址自增偏移量大小再将Rd的数据写入到以基地址为首地址的内存中
ldr Rd[基地址偏移量]
先将基地址自增偏移量大小再从基地址为首地址到内存中读取数据保存到Rd中
注基地址要保存到一个寄存器中偏移量要是一个立即数 此外还可以通过寄存器列表对内存批量读写
写
stm 基地址 { 寄存器列表}
将寄存器列表中的所有寄存器数据写入到以基地址为首地址的内存中
读
ldm 基地址{寄存器列表}
从基地址开始往下读取数据保存到寄存器列表中的每一个寄存器中
注 寄存器的写法有起始寄存器-终止寄存器 /寄存器1、寄存器2、、、、 并且无论寄存器列表编号顺序与否排列内存读写始终是从小编号寄存器对应着低地址的数据
批量寄存器地址的增长方式有以下四种
ia、ib、da、db a先读写基地址再增长
b基地址先增长再进行读写
i基地址往大地址方向增长
d基地址往小地址方向增长
栈内存读写
1.空栈和满栈EF
2.增栈和减栈AD
也就形成了四类栈空增EA空减ED满增FA满减FD
ARM默认使用满减栈(FD)
交叉读写即ia写那就db读
对于ARM满减是由ib写入那么就需要用da读出对应满减栈就是先读再偏移
满减栈的实现主要通过三种方式压栈出栈、strdb和满减栈专用的后缀fd
1.压栈出栈
push {寄存器列表}
pop {寄存器列表}
start
mov sp ,#0x40000020 初始化的栈
mov R1, #0x1
mov r2,#0x2
mov r3,#0x3
push {R1-r5}
2.stmdb
将上述代码的push替换成stmdb
3.stmfd满减专用
push换成stmfd
最后就是关于叶子函数和非叶子函数的压栈出栈注意事项
关于叶子函数为了叶子函数在操作寄存器时不改变非叶子函数的需求通常将从非叶子函数中已经使用且叶子函数中要使用寄存器数据进行压栈处理在叶子函数处理完之后进行出栈释放从而保证函数返回后寄存器的值和调用函数前的保持一致
针对于非叶子函数还要额外的将返回地址进行压栈出栈处理将LR寄存器压栈非叶子函数调用完成后将其中 的地址数据出栈于sp寄存器中使程序继续正常运行
核心即压栈保护现场push{}出栈恢复现场pop{} 1.2.8状态寄存器传送指令
读取状态寄存器
mrs Rd,cpsr
读取CPSR的数值保存到Rd中
修改状态寄存器
MSR cpsr sh
修改cpsr寄存器的数值为操作数
注在特权模式下可以通过修改CPSR到非特权模式USER模式但是非特权模式不能通过修改cpsr寄存器的数值实现转化为特权模式只有当对应的特权事件发生之后处理器会自动进入对应的特权模式
1.2.9异常产生指令
1.2.9.1软中断产生指令
当软中断产生指令执行后会产生一个如饭中断让处理器进入SVC模式下进行软中断的处理
swi sh
sh是一个立即数即产生软中断的中断号
例子 start
MRS r0 cpsr
Msr cpsr#0x1
swi 1
loop
b loop
end 1.2.9.2异常模式和异常源
前者时处理器发生异常后进入的工作模式后者是引发处理器产生异常的源头
总共分为五种异常模式和7种异常源 异常向量表
ARM处理器在处理异常时采用了异常向量机制通过在内存中申请一段空间为异常向量表作为异常处理程序的索引项根据索引项进入异常处理程序去执行。
cortex——a处理器的异常向量表时32字节平分为8份。每一份时44字节正好对应一条汇编指令每一种异常源都会在异常向量表中有一个位置剩下一份位置保留
1.2.9.3异常的处理4⃣️大步3⃣️小步
1.保存cpsr于spsr
2.修改cpsr三小步 修改为对应的异常模式【40】 修改工作状态为ARM状态【5】-》0 根据当前的异常的优先级禁用中断【7:6】
3.保存程序的返回地址到异常模式的LR寄存器中
4.修改PC的值到对应异常在异常向量表中的位置
1.2.9.4异常的返回
注异常的返回必须要手动返回
1.将异常模式下的spsr数值赋值给cpsr恢复程序的状态
2.将异常模式下的LR的数值赋值给PC恢复程序执行的位置 1.2.10协处理器指令
2.伪操作:能够在编译过程中起到编译引导作用的 内容
.test .gloabal .if .else ..endif . .....
3.伪指令不是汇编指令但是可以起到指令的作用也会占用一定的内存空间
4.注释
单行注释 或
多行注释/**/
条件注释
.if 逻辑值 指令段
.else 指令段
.endif
5.混合编程
目的使c语言资源和汇编资源相互调用
要求符合ATPCS规范将变量传递给从低到高的寄存器实现二者之间的相互调用
函数与标签函数名汇编中当标签使用标签c语言中当函数名使用
内联汇编格式
asm volatile
汇编指令\n\t
。。。。。。
输出列表
输入列表
破坏列表