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,需要修改的操作

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

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

相关推荐
AI的探索之旅4 小时前
AI辅助原理图评审:电源去耦、BOOT引脚、VCAP——19项逐一核查,遗漏?不存在的
人工智能·vscode·嵌入式硬件
茯苓gao4 小时前
嵌入式开发笔记:EtherCAT协议从硬件到软件完整配置指南——从零搭建一套EtherCAT通信系统
笔记·嵌入式硬件·学习
GeekArch4 小时前
第24讲:Vibe模式代码风格控制——适配Keil/STM32工程规范
人工智能·stm32·单片机·嵌入式硬件·mcu·决策树·ai编程
Freedom_my5 小时前
STM32项目3
stm32·单片机·嵌入式硬件
国科安芯6 小时前
星间光链路:AS32S601型抗辐射MCU在空间激光通信终端控制中的技术实现
服务器·网络·单片机·嵌入式硬件·物联网·安全·信息与通信
小李不困还能学7 小时前
基于 51 单片机的8 路抢答器设计教程
单片机·嵌入式硬件·mongodb·抢答器
CedarQR8 小时前
万字长文:从零在 RK3588 上部署 PaddleSpeech 中文 TTS 全流程(FastSpeech2 + HiFiGAN)
开发语言·c++·嵌入式硬件·ubuntu·json
萌动的小火苗8 小时前
嵌入式开发中的栈与队列:任务调度为什么依赖数据结构
数据结构·c++·单片机·嵌入式硬件
振浩微433射频芯片9 小时前
工业遥控器总在关键时刻“掉链子”?——433MHz芯片方案如何破局
网络·单片机·嵌入式硬件·物联网·工业遥控
三易串口屏10 小时前
三易串口屏开发教程:如何使用键盘控件输入参数并发送给单片机
单片机·嵌入式硬件·串口屏·三易串口屏·键盘控件