ARM汇编基础知识

本文深入解析了RISC架构的ARM芯片,如乘法指令的实现,以及CISC架构的X86如何通过微程序处理复杂指令。同时介绍了小端和大端存储的概念,以及寄存器操作、栈的作用和常见运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.RISC和CISC
ARM芯片属于精简指令集计算机(RISC: Reduced Instruction Set Computing)
它所用的指令比较简单,有如下特点:
①对内存只有读、写指令
②对于数据的运算是在CPU内部实现
③使用RISC指令的CPU硬件复杂度小一点,易于设计
在RISC中乘法计算ab计算要使用四条汇编指令
X86属于复杂指令集计算机(CISC: Complex Instruction Set Computing)
它所用的指令比较复杂,比如某些复杂的指令,它是通过‘微程序’来实现的。
比如执行乘法指令时,实际上会去执行一个‘微程序’
在微程序里一样是去执行四步操作:
①读内存a
②读内存b
③计算a
b
④把结果写入内存
2.什么是小端存储?什么是大端存储?
小端存储就是其存储格式为保存的字最低地址的字节看作是最低位字节,最高地址字节被看作是最高位字节。因此,存储器系统字节0连接到数据线7-0。
大端存储就是其存储格式为将最高位字节保存在最低地址字节,最低位字节保存在最高地址字节。因此存储器系统字节0连接到数据线31-24。
3.mov r0,#val val必须符合某些规定,称作立即数
4.若不是立即数,可使用伪指令 ldr r0,=val
如ldr r0,=0x12345678 0x12345678不是立即数,会替换为
ldr r0,[pc,#offset] 使用load register读内存指令读出值,offset是链接程序时确定的

label dcd 0x12345678 编译器在程序某个地方保存这个值
5.adr伪指令 用来读某个标号的地址
例adr r0,loop
伪指令会被替换为adr r0,pc,#val val在链接程序时确定
6.例程
mov r0,#0x20000 ;将立即数0x20000存入r0寄存器
mov r1,#0x10 ;将立即数0x10存入r1寄存器
mov r2,#0x12 ;将立即数0x12存入r2寄存器
str r2,[r0] ;将r2寄存器的值存入r0寄存器的值所指向的内存地址
str r2,[r0,#4] ;将r2寄存器的值存入r0寄存器的值所指向的内存地址偏移4个字节
str r2,[r0,#8]! ;将r2寄存器的值存入r0寄存器的值所指向的内存地址偏移8个字节后,更新0x20000+8为R0寄存器所存的值
str r2,[r0,r1] ;将r2寄存器的值存入r0寄存器的值+r1寄存器的值所指向的内存地址
str r2,[r0,r1,lsl #4] ;将r2寄存器的值存入r0寄存器的值+r1寄存器的值左移4位所指向的内存地址
str r2,[r0],#0x20 ;将r2寄存器的值存入r0寄存器的值所指向的内存地址后,更新0x20000+8+0x20为R0寄存器所存的值
mov r2,#0x32 ;将立即数0x32存入r2寄存器
str r2,[r0] ;将r2寄存器的值存入r0寄存器的值所指向的内存地址
ldr r3,[r0],+r1,lsl #1 ;将r0寄存器的值所指向的内存地址的值存入r3寄存器,更新r0寄存器的值为r0+r1寄存器的值左移1位
7. stm和ldm有四种地址模式。
ia–Increment After,每次传输后才增加Rn的值(默认,可省略)
ib–Increment Before,每次传输前就增加Rn的值(ARM指令才能用)
da–Decrement After,每次传输后才减少Rn的值(ARM指令才能用)
db–Decrement Before,每次传输前就减少Rn的值
stm ldm例程
mov r1,#1 ;将立即数1存入r1寄存器
mov r2,#2 ;将立即数2存入r2寄存器
mov r3,#3 ;将立即数3存入r3寄存器
mov r0,#0x40000 ;将立即数0x40000存入r0寄存器
stmdb r0,{r1-r3} ;在ARM Cortex-A(armV7)编程手册V4.0中指明,{r1-r3}被读取或被写入顺序与在花括号中的顺序无关,而是按照固定顺序:标号越小的寄存器写入越低的地址。则结果即为先将r0寄存器的值减四(四个字节–一个字–32位)地址对应为r3寄存器的值,依次往下。

在这里插入图片描述
8.栈的作用:将寄存器的值保存到内存当中,又将内存中的值读回到寄存器中就是栈的作用,即保存现场。现场就是寄存器中的值,调用某个函数之前,先把寄存器中当前的值保存到栈中,栈是一堆内存,调用完函数之后,再将栈中的值恢复到寄存器中去。
栈有四种方式:
根据栈指针指向,可分为满(Full)/空(Empty)
满SP指向最后一个入栈的数据,需要先修改SP再入栈
空SP指向下一个空位置,先入栈再修改SP
根据压栈时SP的增长方向,可分为增/减
增(Ascending):SP变大
减(Descending):SP变小
组合后,就有四种方式:
满增、满减
空增、空减
常用的“满减”:
入栈时用STMDB,也可以用STMFD,作用一样;
出栈时用LDMIA,也可以用LDMFD,作用一样;
mov r1,#1 ;将立即数1存入r1寄存器
mov r2,#2 ;将立即数2存入r2寄存器
mov r3,#3 ;将立即数3存入r3寄存器
mov sp,#0x20000 ;将立即数0x20000存入sp寄存器
stmfd sp!,{r1-r3} ;先将SP-4,将r3寄存器的值存入SP-4地址指向的空间,并如法炮制依次向SP-8、SP-12存入R2 R1,最后令SP=SP-12
mov r1,#0
mov r2,#0
mov r3,#0
ldmfd sp!,{r1-r3} ;先将SP地址指向的空间存的值读出放入r1,并将SP+4,如法炮制将SP+4 、SP+8地址指向的值依次读出存入R2 R3,最后将令=SP+12

9.常用运算
加法指令add:
add r1,r2,r3 ;r1=r2+r3
add r1,2,#0x12 ;r1=r2+0x12
减法指令sub:
sub r1,r2,r3 ;r1=r2-r3
sub r1,r2,#0x12 ;r1=r2-0x12
位操作:
;VisUAL里不支持(1<<4)这样的写法,写成:0x10
and r1,r2,#(1<<4) ;位与,r1=r2&(1<<4)
and r1,r2,r3 ;位与, r1=r2&r3
bic r1,r2,#(1<<4) ;清除某位,r1=r2&~(1<<4)
bic r1,r2,r3 ;清除某位,r1=r2&~r3
orr |
比较:
cmp r0,r1 ;比较r0,r1的结果
cmp r0,#0x12 ;比较r0,0x12的结果
tst r0,r1 ;测试r0&r1的结果
tst r0,#(1<<4) ;测试r0&(1<<4)的结果
以上数据处理结果若为负数、零值、进位、上溢或下溢,大于等于会影响程序状态寄存器CPSR
在这里插入图片描述
10.条件执行
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值