2440栈的实现类型、b系列指令、汇编掉用c、c调用汇编、切换工作模式、初始化异常向量表、中断处理、

我要成为嵌入式高手之4月11日51ARM第六天!!


b指令

标签:表示这条指令的名称,可跳转至标签

b指令:相当于goto,可随意跳转

如:finish为标签,b finish跳转至该位置

finish

b finish

bl指令:跳转之后将跳转前的位置存储到 lr(链接寄存器) 寄存器中

bx指令:将某个寄存器的保存的地址写入 pc 寄存器

练习:用汇编写出1~100的累加和

cs 复制代码
	area reset, code, readonly
	code32
	entry
	
	mov r0, #0
	mov r1, #0

loop
	add r1, r1, r0
	add r0, #1
	
	cmp r0, #100
	ble loop

finish
	b finish

	end

2440栈的实现类型

2440实现保护和恢复现场使用的栈是数组栈,即用一段连续的内存空间为栈提供空间。从数组栈的具体实现来看入栈的方式有四种做法:

  1. 空增:先写入数据,再让栈指针自增;
  2. 空减:先写入数据,再让栈指针自减;
  3. 满增:先让栈指针自增,再写入数据;
  4. 满减:先让栈指针自减,再写入数据。

arm体系采用的方案是满减 ,但是在进行操作之前,我们必须告诉2440栈底的位置,这里我们把栈底设置为0x40001000,从地址0x40000000开始的0x1000这段内存空间对应的是2440内部的一段ram,总共4k。实际能够使用的内存空间为[0x40000000~0x40000FFF],

设置栈底指针寄存器: ldr sp =0x40001000

入栈保护指令stmfd(STMDB)

STMFD<c> <Rn>{!}, <registers>

其中Rn表示栈底指针寄存器,< registers >表示需要入栈保护的寄存器,!表示入栈之后sp自动自减。如:stmfd sp!, {r0, r1, r2, r3-r12, lr}

出栈恢复指令ldmfd(LDM/LDMIA/)

LDMFD<c> <Rn>{!}, <registers>

中Rn表示栈底指针寄存器,< registers >表示需要入栈保护的寄存器,!表示出栈之后sp自动自增。如:ldmfd sp!, {r0, r1, r2, r3-r12, lr}

汇编程序中调用c程序函数

步骤:

1、先用 import 声明c函数

如: import c_add

2、入栈保护{r0 - r12}

3、若是函数参数小于4个时,通过 r0 ~ r3 寄存器进行传参

4、函数调用完的返回值结果通过 r0 寄存器返回

5、若参数个数大于4个,从第五个开始要通过栈进行参数传参

6、出栈恢复{r0 - r12}

cs 复制代码
	import c_add
	stmfd sp!, {r0-r12}
	mov r0, #1
	mov r1, #2 
	mov r2, #3
	mov r3, #4 
	mov r4, #5
	stmfd sp!, {r4}
	bl c_add
	ldmfd sp!, {r4}
	ldmfd sp!, {r0-r12

c程序中掉用汇编函数

1、import main

2、b main

3、export 汇编函数名

4、在main中声明汇编函数

5、在汇编函数结尾bx lr

如何切换工作模式

1、把r0中低5位清零

2、把r0中低五位设置为10000(user模式)

3、用msr指令将r0的值写入cpsr寄存器

cs 复制代码
	ldr sp, =0x40001000
	bic r0, r0, #0x1F
	orr r0, r0, #0x10
	msr cpsr_c, r0

为什么此处sp变为0?

答:此时的sp为sp_svc,不是user模式下的sp,故需要设置sp_user,且要从栈顶往后走1k

cs 复制代码
	ldr sp, =0x40001000
	bic r0, r0, #0x1F
	orr r0, r0, #0x10
	msr cpsr_c, r0

	ldr sp, =0x40001000
	sub sp, sp, #1024

cpsr中指令

msr指令:写入cpsr

mrs指令:读取cpsr中数据

启动代码

异常向量表

初始化代码:

cs 复制代码
	preserve8
	area reset, code, readonly
	code32
	entry
	
	;用8个代码占用异常向量表的八个格式
	b start
	nop
	nop
	nop
	nop
	nop
	nop
	nop

start
	ldr sp, =0x40001000
	
	;状态切换到user模式下
	mrs r0, cpsr
	bic r0, #0x1F
	orr r0, #0x10
	msr cpsr_c, r0
	ldr sp, =0x40001000
	sub sp, sp, #1024
	import main
	b main
	

finish
	b finish


	end

中断处理

中断类型:

软件中断SWI

SWI指令:发出一个软件中断,用法:SWI #立即数

作用:产生一个软件中断

流程 :产生一个异常,进入svc模式;查询异常向量表(找软件中断0x08)

cs 复制代码
	;用8个代码占用异常向量表的八个格式
	b start
	nop
	b do_swi
	nop
	nop
	nop
	nop
	nop

start
	;设置的是svc下的栈指针寄存器
	ldr sp, =0x40001000
	
	;状态切换到user模式下
	mrs r0, cpsr
	bic r0, #0x1F
	orr r0, #0x10
	msr cpsr_c, r0
	ldr sp, =0x40001000
	sub sp, sp, #1024
	import main
	b main

do_swi
	import swi_handle
	stmfd sp!, {r1-r12, lr}
	bl swi_handle
	ldmfd sp!, {r1-r12, pc}^
	;^含义:不但要恢复现场,并且要恢复之前的工作模式
		
	export asm_swi
asm_swi
	swi #10
	bx lr
	;在写完函数之后都应该加上bx lr:将lr写入pc中

IRQ快速中断

初始化IRQ模式栈指针寄存器

cs 复制代码
	preserve8
	area reset, code, readonly
	code32
	entry
	
	;用8个代码占用异常向量表的八个格式
	b start
	nop
	b do_swi
	nop
	nop
	nop
	b do_interrupt
	nop

start
	;设置的是svc下的栈指针寄存器
	ldr sp, =0x40001000
	
	;状态切换到user模式下
	mrs r0, cpsr
	bic r0, #0x1F
	orr r0, #0x12;切换到IRQ模式
	bic r0, r0, #(1 << 7);将中断允许清零,意为允许中断
	msr cpsr_c, r0
	
	;初始化的是IRQ模式下的栈指针寄存器
	ldr sp, =0x40001000
	sub sp, sp, #1024

	mrs r0, cpsr
	bic r0, #0x1F
	orr r0, #0x10
	msr cpsr_c, r0
	ldr sp, =0x40001000
	sub sp, sp, #2048
	
	import main
	b main

do_interrupt
	import interrupt_handle
	sub lr, lr, #4;查询中断类型表得出快速中断需要lr寄存器的值-4
	stmfd sp!, {r1-r12, lr}
	bl interrupt_handle
	ldmfd sp!, {r1-r12, pc}^


do_swi
	import swi_handle
	stmfd sp!, {r1-r12, lr}
	bl swi_handle
	ldmfd sp!, {r1-r12, pc}^
	;^含义:不但要恢复现场,并且要恢复之前的工作模式
		
	export asm_swi
asm_swi
	swi #10
	bx lr
	;在写完函数之后都应该加上bx lr:将lr写入pc中	

finish
	b finish


	end

MINI2440

将软件写入MINI2440,需要修改的操作

若将软件下载进板子成功,会出现如此字样

调试结果与软件调试结果应一致

相关推荐
森旺电子1 小时前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
不过四级不改名6773 小时前
蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)
stm32·嵌入式硬件·蓝桥杯
小A1594 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
Rorsion4 小时前
各种电机原理介绍
单片机·嵌入式硬件
善 .7 小时前
单片机的内存是指RAM还是ROM
单片机·嵌入式硬件
超级码农ProMax7 小时前
STM32——“SPI Flash”
stm32·单片机·嵌入式硬件
Asa3197 小时前
stm32点灯Hal库
stm32·单片机·嵌入式硬件
end_SJ9 小时前
初学stm32 --- 外部中断
stm32·单片机·嵌入式硬件
gantengsheng10 小时前
基于51单片机和OLED12864的小游戏《贪吃蛇》
单片机·嵌入式硬件·游戏·51单片机
嵌入式小强工作室11 小时前
stm32 查找进硬件错误方法
stm32·单片机·嵌入式硬件