1.块存储指令(批量操作)
ldm:将一块连续空间的内容拷贝到一组寄存器中
stm:将一组寄存器中的内容拷贝到一块连续的空间中
i:地址变化方向从小到大
d:地址变化方向从大到小
a:指针指向的空间没有值,需要先操作,后增加
b:指针指向的空间有值,需要先增加后操作
ia ib da db
ARM最常用的是ia
ldmia stmia
ldmia r0!,{r1-r6} @将r0地址处的内容依次拷贝到r1-r6寄存器中,!表示会更新r0的值
stmia r0,{r1-r6} @将r1-r6寄存器的内容依次拷贝到r0所指向的内存中
.text
@将str1的值拷贝给str2
ldr r1,=str1
ldr r2,=str2
ldmia r1!,{r3-r4}
stmia r2!,{r3-r4}
nop
nop
.data
str1:
.string "abcde\0" @定义字符串
str2:
.space 10 @申请10个字节空间
.end
2.堆栈操作指令
只是用来操作栈区的,保存地址的指针肯定是sp
增:地址变化方向从低到高 a
减:地址变化方向从高到低 d
满:栈顶有数据 f
空:栈顶没有数据 e
ARM使用的是满减栈 stmfd ldmfd
3. 8种寻址方式
>立即数寻址 mov r0,#1
>寄存器寻址 mov r0,r1
>寄存器间接寻址 ldr r0,[r1]
>寄存器移位寻址 mov r0,r1,lsl #1
>基址变址寻址 ldr r0,[r1,#4]
>多寄存器寻址 ldmia r0, {r1-r5}
>相对寻址 b aa
回忆:相对路径 相对.
绝对路径 从/开始
相对地址:相对pc的地址--》偏移量
绝对地址:真正的从0开始的地址
>堆栈寻址 stmfd
4.swi指令
5种异常模式 7种异常源
其中:复位、fiq、irq是硬件产生的异常,一般称为中断
目标:
- 学习swi的作用
- 异常处理流程
信号的处理需要满足三个条件:
- 信号源 --- 随机产生的
- 信号处理函数
- 信号源和信号处理函数要绑定
异步:随机的
同步:有节奏的
mrs r0, cpsr @将cpsr的值拷贝到r0
msr cpsr, r0 @将r0的值拷贝到cpsr
MSR cpsr或spsr_<域>,操作数
<域>用来设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域
【31-24】:条件标志位域,用f表示
【23-16】:状态位域,用s表示
【15-8】:扩展位域,用x表示
【7-0】:为控制位域,用c表示
可用来指明要操作的域
比如:
msr cpsr,r0 传送r0的内容到cpsr
msr cpsr_c,r0 传送r0的值内容到cpsr,但仅仅修改cpsr中的控制位域
swi指令:实现系统调用
open----->2 read----->3 write------>4
open()
{
swi 2
}
swi_handler:
//通过软中断号知道是哪个系统调用
如果是open open_sys
如果是read read_sys
如何得到软中断号?
- swi是在译码时就发生跳转,所以将pc的值赋值给了lr,是swi的下一条指令的地址,lr-4就是swi指令的地址
- 得到swi的机器码:sub r0, lr,#4 ldr r1,[r0]
- 得到软中断号 bic r1, #0xff000000
.text
@异常向量表
b reset @reset
nop @undef
@b swi_handler @swi
ldr pc,=swi_handler @伪指令,将swi指令的跳转范围绑定pc的跳转范围,扩大swi指令的跳转范围
nop @prefetch abort
nop @data abort
nop @reserved
nop @irq
nop @fiq
reset:
@给svc模式的sp赋值
ldr sp,=stack_svc_top
@切换到user模式
mrs r0, cpsr
bic r0, #0x1f @3-0位清0
orr r0, #0x10 @user模式----4-0位:10000
msr cpsr, r0
b main
@异常处理函数
swi_handler:
@入栈保存现场 将共用的寄存器的值入栈
stmfd sp!,{r0-r12,lr}
nop
mov r0,#0xff
mov r1,#0xdd
mov r2,#0xcc
nop
@得到软中断号
sub r3,lr,#4
ldr r4,[r3]
bic r4,#0xff000000 @将31-24位清0
@如果是2 open
cmp r4,#2
bleq open_sys
@如果是3 read
cmp r4,#3
bleq read_sys
nop
nop
nop
swi_handler_end:
@恢复出栈现场
ldmfd sp!,{r0-r12,pc}^ @ ^----->将spsr的值赋值给cpsr
@切换到user模式
@mrs r5, spsr
@msr cpsr, r5
main:
nop
nop
nop
mov r0,#1
mov r1,#2
mov r2,#3
swi 2 @异常源 open
nop
nop
swi 3 @read
main_end:
b main_end
open_sys:
ldr r5,=0xaaaaa @伪指令
nop
nop
open_sys_end:
mov pc,lr
read_sys:
ldr r5,=0xbbbbb @伪指令
nop
nop
read_sys_end:
mov pc,lr
@申请堆栈空间
.data
stack_svc:
.space 100 @申请100个字节的内存空间
stack_svc_top: @将sp(栈顶指针)挪到栈顶
.end