2440栈的实现类型、b系列指令、汇编掉用c、c调用汇编、切换工作模式、初始化异常向量表、中断处理、 我要成为嵌入式高手之4月11日51ARM第六天!! ————————————————————————————

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

b指令

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

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

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

finish
    b finish   

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

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

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

	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}

	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寄存器

	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

	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中数据

启动代码

异常向量表

初始化代码:

	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)

	;用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模式栈指针寄存器

	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. 成为嵌入高手126十一!!

    2024-04-15 06:42:03       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-15 06:42:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-15 06:42:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-15 06:42:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-15 06:42:03       20 阅读

热门阅读

  1. 2024.4.17 Python爬虫复习day05 可视化

    2024-04-15 06:42:03       16 阅读
  2. ARM的TrustZone技术

    2024-04-15 06:42:03       40 阅读
  3. 人工智能常见的分类算法

    2024-04-15 06:42:03       15 阅读
  4. Go语言异常处理方式

    2024-04-15 06:42:03       12 阅读
  5. ASP.NET基于BS方式的即时通讯软件的设计与实现

    2024-04-15 06:42:03       17 阅读
  6. [leetcode 链表] 反转链表 vs 链表相交

    2024-04-15 06:42:03       15 阅读
  7. Docker搭建Emby

    2024-04-15 06:42:03       46 阅读
  8. .Net 里面WhenAll的解释和用法

    2024-04-15 06:42:03       18 阅读
  9. 智能指针三剑客:shared_ptr

    2024-04-15 06:42:03       12 阅读
  10. 【LeetCode刷题记录】189. 轮转数组

    2024-04-15 06:42:03       17 阅读
  11. C语言--内存函数

    2024-04-15 06:42:03       12 阅读
  12. Zookeeper+Kafka

    2024-04-15 06:42:03       14 阅读
  13. Flume配置案例@Source:Kafka,Channel:File,Sink:HDFS

    2024-04-15 06:42:03       15 阅读
  14. 计算机视觉(CV)技术的优势和挑战

    2024-04-15 06:42:03       16 阅读