[und&swi]异常模式


本文是基于韦东山视频的学习笔记

汇总点这

und 异常(无定义异常)

我们在执行 main 函数之前加入句子

.word 0xdeadc0de	//故意加入未定义句子

首先,代码执行至此,出现了 und 异常,根据异常向量表

这里是引用

出现 und 异常后会跳转到 0x00000004 地址去处理异常,所以我们需要在0x00000004 加入处理异常的跳转:

_start:
	b reset	/* 0x00000000 */
	b und	/* 0x00000004 */

而 und 写什么呢,根据上篇博文,大概笼统地可以理解为

  1. 保护现场
  2. 处理
  3. 恢复现场
_start:
	b reset	/* 0x30000000 */
//	ldr pc, =do_und	/* 0x30000004 */
	ldr pc, und_addr	

/* 这里为什么这么做
 * ldr pc, und_addr 强制加载到这里,这里再强制加载到 do_und
 * 如果不是,由于"ldr pc, =do_und" 是一条伪指令,do_und这个地址就会被编译器默认保存在编译文件最后的地址
 * 修改后就能达到:“直接跳到接着上一句的地址执行,而不用跳到最后的地址”的目的
 */
und_addr:
	.word do_und

do_und:
	/* 重要!栈未设置,需要重新设置,指向一个不会被用到的地方 */
	ldr sp, =0x34000000
	
	/* 保护现场 */
	stmdb sp!, {r0-r12, lr}			//目前位置 lr 里面有异常前的下一条将要执行的指令,所以也要保存
	
	/* 处理异常 */
	mrs r0, cpsr	//读cpsr的值,作为print_und_exception的第一个参数
	ldr r1, =und_string	//r1 载入字符串,作为print_und_exception的第二个参数
	ldr pc, =print_und_exception

	/* 恢复现场 */
	ldmia sp!, {r0-r12, pc}^	/* ^会把spsr的值恢复到cpsr里 */

und_string:
	.string "und exception!!!"

.align (4)	// 4 zijie duiqi

swi 异常(软中断异常)

之前提过,除了usr模式之外,其他模式都可以都过寄存器任意切换,但恰恰app运行情况下一般情况都是usr模式。如果想切到其他模式,那就可以通过中断或者异常来实现,其中swi(软件异常)是最为常用的手段。软件异常进入的是svc模式。

事实上,swi 异常和 und 异常大同小异,照着印就可以。

swi  0x123	//加入swi异常

这里是引用

代码都是大同小异

swi_addr:
	.word do_swi

do_swi:
	/* 重要!栈未设置,需要重新设置,指向一个不会被用到的地方 */
	ldr sp, =0x33e00000
	
	/* 保护现场 */
	stmdb sp!, {r0-r12, lr}			//目前位置 lr 里面有被打断前的下一条将要执行的指令,所以也要保存

	/* 调用c函数会破坏lr寄存器,所以要提前保护
 	 * 根据ATPCS规则,c函数调用完会恢复r4-r11的寄存器,所以可以r4来保存
	 */
	mov r4, lr	
	
	/* 处理异常 */
	mrs r0, cpsr	//读cpsr的值,作为print_swi_exception的第一个参数
	ldr r1, =swi_string	//r1 载入字符串,作为print_swi_exception的第二个参数
	bl print_swi_exception

	sub r0, r4, #4	/* lr是保存异常前下一条指令的地址,减4后,r0就是swi异常的句子*/
	bl print_swi_val

	/* 恢复现场 */
	ldmia sp!, {r0-r12, pc}^	/* ^会把spsr的值恢复到cpsr里 */
	
swi_string:
	.string "swi exception!!!"

.align (4)	// 前面是字串,后面必须4字节对齐

其中不同的是,swi异常的值是可以打印出来的,通过lr寄存器和print_swi_val函数实现的。

void print_swi_val(unsigned int *pswi)
{
	puts("\n\rswi_val = ");
	print_hex(*pswi & ~(0xff000000));
	puts("\n\r");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值