tiny6410裸机实验第7章--------------异常(代码)

【说明】

              前一节我们介绍了异常的原理,并解释了一部分代码的意思,这一节贴出完整的代码,方便没有源码的童鞋,只贴出START.S  因为其他的和前面几章一样的。


【源代码】

 

.globl _start
_start:
        // 异常向量表
        b reset                                         /* 复位时,cpu跳到0地址 */
        ldr     pc, _undefined_instruction  /* 未定义指令异常 */
        ldr     pc, _swi                            /* swi异常,进入svc模式 */
        @ldr    pc, _prefetch_abort                     /* 预取中止异常 */
        @ldr    pc, _data_abort                 /* 数据访问异常 */
        @ldr    pc, _not_used                   /* 没用到 */
        @ldr    pc, _irq                        /* 中断异常 */
        @ldr    pc, _fiq                        /* 快中断异常 */


reset:
        // 外设地址告诉cpu
    ldr r0, =0x70000000
    orr r0, r0, #0x13
    mcr p15,0,r0,c15,c2,4
    
        // 关看门狗
        ldr r0, =0x7E004000
        mov r1, #0
        str r1, [r0]

        // 设置栈
        ldr sp, =8*1024

        // 初始化时钟
        bl clock_init

        // 初始化ddr
        bl sdram_init

        // 初始化uart
        bl init_uart

        // 初始化nandflash
        bl nand_init

        // 重定位,把程序的代码段、数据段复制到它的链接地址去
        adr r0, _start   
        ldr r1, =_start  
        ldr r2, =bss_start      
        sub r2, r2, r1
        cmp r0,r1
        beq clean_bss
        bl copy2ddr
        cmp r0, #0
        bne halt

        // 清BSS,把BSS段对应的内存清零
clean_bss:
        ldr r0, =bss_start
        ldr r1, =bss_end
        mov r3, #0
        cmp r0, r1
        beq on_ddr
clean_loop:
        str r3, [r0], #4
        cmp r0, r1
        bne clean_loop

        // 跳转
        ldr pc, =on_ddr

on_ddr:
        // 进入user 模式
        mrs r0, cpsr   
        bic     r0,r0,#0x1f
        orr     r0,r0,#0x10
        msr     cpsr,r0
        ldr sp, =0x57000000                //我们现在内存中了。要重新设置一下SP
        ldr r1, =usr_str
        bl print_cpsr


        // 进入svc 模式
        // cpu进入svc模式
        // 把之前的cpsr保存到spsr_svc
        // 切换到r13_svc, r14_svc
        // 把swi的下一条指令存到r14(lr)_svc
        // 跳到地址8
        swi 0


         // cpu进入Undefined模式
         // 把之前的cpsr保存到spsr_und
         // 切换到r13_und, r14_und
         // 把下一条指令存到r14(lr)_und
         // 跳到地址4
undef:
        .word 0xff000000

        // 跳到main函数
        bl main

halt:
        b halt


        // swi异常
_swi:
        .word swi
swi:
        /* 1. 保存现场 */
        ldr sp, =0x56000000
        stmdb sp!, {r0-r12, lr}             /* lr就是swi的下一条指令地址 */
        /* 2. 处理异常 */
        mrs r0, cpsr
        ldr r1, =swi_str
        bl print_cpsr
        /* 3. 恢复现场 */
        ldmia sp!, {r0-r12, pc}^                /* ^表示把spsr恢复到cpsr */
swi_str:
        .word 0x00697773                                /* 字符串"swi" */


        // 未定义指令异常
_undefined_instruction:
        .word undefined_instruction
undefined_instruction:
        /* 1. 保存现场 */
        ldr sp, =0x55000000
        stmdb sp!, {r0-r12, lr}
        /* 2. 处理异常 */
        mrs r0, cpsr
        ldr r1, =und_str
        bl print_cpsr
        /* 3. 恢复现场 */
        ldmia sp!, {r0-r12, pc}^                /* ^表示把spsr恢复到cpsr */
und_str:
        .word 0x00646e75                                /* 字符串"und" */


usr_str:
        .word 0x00727375                                /* 字符串"usr" */


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值