当前位置:首页 > 芯闻号 > 充电吧
[导读]今天犯了一个小错误,调试了几个小时;最后重新分析了几遍反汇编才发现。万丈高楼平地起、勿以浮沙驻高台。错误代码:.text .global _start _start:     b reset     

今天犯了一个小错误,调试了几个小时;最后重新分析了几遍反汇编才发现。万丈高楼平地起、勿以浮沙驻高台。

错误代码:

.text
.global _start
_start:
    b reset
    ldr pc,=und_addr
    ldr pc,=swi_addr

und_addr:
    .word undef

swi_addr:
    .word swi_handle

undef:

    ldr sp,=0x32000000 //处理异常调用C函数,设置und模式下的栈,以前是usr模式
    //保存现场
    stmdb sp!,{r0-r12,lr}
    bl print2
    //处理异常
    mrs r0,cpsr //und模式下的cpsr寄存器,也可以改为输出spsr低5位和usr模式的cpsr相同
    ldr r1,=und_string
    bl printException
    //恢复现场
    ldmia sp!,{r0-r12,pc}^

und_string:
    .string "undefined instruction exception"

.align 4


swi_handle: 
    ldr sp,=0x33000000 //处理异常调用C函数,设置svc模式下的栈,以前是usr模式
    //保存现场
    stmdb sp!,{r0-r12,lr}
    //处理异常
    mrs r0,cpsr //und模式下的cpsr寄存器,也可以改为输出spsr低5位和svc模式的cpsr相同
    ldr r1,=swi_string
    bl printException
    //恢复现场
    ldmia sp!,{r0-r12,pc}^

swi_string:
    .string "swi exception"

.align 4    

reset:
//关看门狗
    ldr r1,=0x53000000
    ldr r0,=0
    str r0,[r1]

//设置时钟
    //① 设置锁定时间LOCKTIME
    ldr r1,=0x4C000000
    ldr r0,=0xFFFFFFFF
    str r0,[r1]

    //② 设置分频系数,使得FCLK:HCLK:PCLK = 8:4:1
    ldr r1,=0x4C000014
    ldr r0,=0x5
    str r0,[r1]

    //③ 根据2440规则,由于②中HDIVN!=0 -> CPU总线模式从快速总线模式到异步模式
    mrc p15,0,r0,c1,c0,0
    orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
    mcr p15,0,r0,c1,c0,0

    //④ 设置PLL,设置完PLL后,PLL开始工作,锁定时间内CPU停止工作
    /* 设置FCLK = 400MHZ,HCLK = 100MHZ, PCLK = 100MHZ 
     * Mpll(FCLK) = (2*m * Fin) / (p * 2^s)
     * m = M(MDIV) (the value for divider M)+ 8,
     * p = P(PDIV) (the value for divider P) + 2, s = SDIV
     * MDIV = 92(0x5c), PDIV = 1 , SDIV = 1 
     * FCLK = (2*100*12MHZ) / (3*2^1) = 400MHZ */
     ldr r1,=0x4C000004
     ldr r0,= ((92<<12) | (1<<4) | (1<<0))
     str r0,[r1]

//判断启动方式
    mov r1,#0 // r1 = 0;
    ldr r0,[r1] // r0 = [0];将0地址的值备份
    str r1,[r1] // 将0写入0地址
    ldr r2,[r1] // 再将0地址的值读出来给r2
    cmp r1,r2   // 比较r1和r2,即比较0地址原来的值和写入的值
    ldr sp,= 0x40000000 + 4096 // 先假设为nor启动
    ldreq sp,= 4096 //如果r1==r2,假设不成立为Nand启动
    streq r0,[r1]   // 还原0地址以前的值

    bl sdram_init
    //bl sdram_init2 //用到有初始值的数组,不是位置无关码    
    bl copy2sdram   
    bl clean_bss

    //从复位后的SVC模式切换到USR模式
    //M[4:0] SVC:10011 USR:10000 
    mrs r0,cpsr
    bic r0,r0,#0xf //修改低四位,进入usr模式
    msr cpsr,r0

    //设置usr模式下的栈,sp_usr
    ldr sp,=0x34000000;


    ldr pc,=sdram_next
sdram_next:     
    bl uart0_init
    mrs r0,cpsr  //SVC模式下的cpsr寄存器
    bl print1

    bl print2

    swi 0x1  /* 执行此命令, 触发SWI异常, 进入0x8执行 */

und_code:
    .word 0xeeadc0de  /* 未定义指令 */

    bl main  /* 使用BL命令相对跳转, 程序仍然在NOR/sram执行 */
    //ldr pc, =main  /* 绝对跳转, 跳到SDRAM */

halt:
    b halt

结果:

分析:

sdram.elf:     file format elf32-littlearm

Disassembly of section .text:

30000000:
30000000:   ea00001e    b   3000008030000004:   e59ff110    ldr pc, [pc, #272]  ; 3000011c 
30000008:   e59ff110    ldr pc, [pc, #272]  ; 30000120 

3000000c:
3000000c:   30000014    andcc   r0, r0, r4, lsl r0

30000010:
30000010:   30000050    andcc   r0, r0, r0, asr r0
*************************************************
3000011c:   3000000c    andcc   r0, r0, ip
30000120:   30000010    andcc   r0, r0, r0, lsl r0
*************************************************
30000014:
30000014:   e3a0d432    mov sp, #838860800  ; 0x32000000
30000018:   e92d5fff    stmdb   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
3000001c:   eb000103    bl  3000043030000020:   e10f0000    mrs r0, CPSR
30000024:   e59f10f8    ldr r1, [pc, #248]  ; 30000124 
30000028:   eb000216    bl  300008883000002c:   e8fd9fff    ldmia   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^

30000030:
30000030:   65646e75    strvsb  r6, [r4, #-3701]!
........

发生异常的时候,异常向量表中pc没有跳转到相应的执行函数地址,因为我采用了间接的赋值。两次异常都是跳转到und_addr或者swi_addr开始往后面执行,所以两次都执行了undef处理函数。

更正测试:

①直接赋值到对应执行函数处

.text
.global _start
_start:
    b reset
    ldr pc,=undef
    ldr pc,=swi_handle

反汇编:

sdram.elf:     file format elf32-littlearm

Disassembly of section .text:

***************************************
3000011c:   30000014    andcc   r0, r0, r4, lsl r0
30000120:   30000050    andcc   r0, r0, r0, asr r0
***************************************

30000000:
30000000:   ea00001e    b   3000008030000004:   e59ff110    ldr pc, [pc, #272]  ; 3000011c 
30000008:   e59ff110    ldr pc, [pc, #272]  ; 30000120 

3000000c:
3000000c:   30000014    andcc   r0, r0, r4, lsl r0

30000010:
30000010:   30000050    andcc   r0, r0, r0, asr r0

30000014:
30000014:   e3a0d432    mov sp, #838860800  ; 0x32000000
30000018:   e92d5fff    stmdb   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
3000001c:   eb000103    bl  3000043030000020:   e10f0000    mrs r0, CPSR
30000024:   e59f10f8    ldr r1, [pc, #248]  ; 30000124 
30000028:   eb000216    bl  300008883000002c:   e8fd9fff    ldmia   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^

30000030:
...
30000050:
30000050:   e3a0d433    mov sp, #855638016  ; 0x33000000
...

结果:

② 间接赋值

.text
.global _start
_start:
    b reset
    ldr pc,und_addr
    ldr pc,swi_addr

反汇编:

sdram.elf:     file format elf32-littlearm

Disassembly of section .text:

30000000:
30000000:   ea00001e    b   3000008030000004:   e59ff110    ldr pc, [pc, #272]  ; 3000011c 
30000008:   e59ff110    ldr pc, [pc, #272]  ; 30000120 
*********************
3000011c:   30000014    andcc   r0, r0, r4, lsl r0
30000120:   30000050    andcc   r0, r0, r0, asr r0
*********************

3000000c:
3000000c:   30000014    andcc   r0, r0, r4, lsl r0

30000010:
30000010:   30000050    andcc   r0, r0, r0, asr r0

30000014:
30000014:   e3a0d432    mov sp, #838860800  ; 0x32000000
30000018:   e92d5fff    stmdb   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
3000001c:   eb000103    bl  3000043030000020:   e10f0000    mrs r0, CPSR
30000024:   e59f10f8    ldr r1, [pc, #248]  ; 30000124 
30000028:   eb000216    bl  300008883000002c:   e8fd9fff    ldmia   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^

30000030:
...

30000050:
30000050:   e3a0d433    mov sp, #855638016  ; 0x33000000
...

结果:

总结:

注意ldr pc,=czgldr pc,czg 用法:
①  ldr pc,=czg =》 pc = czg (就是czg标号的地址)
②   ldr pc,czg =》 pc = *(czg) (czg标号地址中放的值)

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

昆山2023年9月15日 /美通社/ -- 万豪旅享家旗下31个非凡品牌之一的万枫酒店今日宣布,昆山万枫酒店盛大开业。昆山市是首批"国家生态园林城市",旅游资源丰富,素有"百戏之祖,昆曲之乡...

关键字: 液晶电视 灯光 调试 高铁

覆盖华东、华北和西部的三大客户创新与应用中心在两年内相继开业 以客户为中心的本地化战略迎来重要里程碑 成都2023年9月7日 /美通社/ -- 生命科学集团赛多利斯持续扩张在华足迹,并于今日正式启用西部区...

关键字: 质量检测 仪器 生物技术 调试

妇科大咖云集 共话日间诊疗新模式 北京2023年3月7日 /美通社/ -- 为进一步推广由郎景和院士牵头,朱兰教授等我国多位著名妇科医学专家共同编著《日间宫腔镜手术中心设置及管理流程中国专家共识》,普及日间宫腔镜诊疗理...

关键字: 东风 内窥镜 编写 调试

在完成应用系统的硬件组装和软件设计以后,便进入系统调试阶段。这个阶段的任务是排除样机中的硬件故 障和纠正软件中的设计错误,并解 决硬件和软件之间的不协调问题 。下面介绍几种调试方法。

关键字: MCS 51 应用系统 调试 加电复位电路

南京2022年12月16日 /美通社/ -- 近日,南瑞集团参建的全国首台(套)单机650MW水电机组全国产调速器、励磁系统在华能糯扎渡水电站#1机组成功投运,为我国水电站核心技术国产化替代提供了“示范样板”。 南瑞集...

关键字: 控制系统 电站 调速器 调试

提供以客户为中心的技术解决方案和服务,助力华北地区生命科学和生物制药行业加速医学发现、简化药物生产 赛多利斯在中国的本地化战略迎来重要里程碑 山东烟台2022年11月1日 /美通社/ -- 生命科学集团赛...

关键字: 生物技术 仪器 蛋白质 调试

从汇编角度来说,如果“test %al, %al”能改成“test %0x1, %al”就没有匪夷所思的问题了,如此一来应该会降低CPU的效率,毕竟执行指令还需要一个立即数,我没搞过编译器也没设计过CPU,纯属瞎猜,能搞...

关键字: 汇编 CPU 编译器

做硬件需要加班吗?有的小伙伴说不加班,到点就走,要加班得提申请,走流程非常麻烦;有的小伙伴说要加班,加到凌晨是常有的事。

关键字: 硬件 调试 装配

研发产品难吗?对于刚刚接触射频硬件设计的我来说非常难,设计和调试、维修不同,调试是在老带新的基础上,按照图纸甚至图纸都不要就可以按照SOP流程得到性能高的产品;维修的话,看懂原理图是必须的,但是你并不需要知道具体的设计参...

关键字: 射频工程师 设计 调试

摘要:针对某公司供热改造工程中,新建背压机组在调试及试运行过程中暴露出的问题进行了梳理分析,并采取了有针对性的应对策略,最终实现了该机组的灵活启停和稳定运行,满足了生产需求。

关键字: 振动 动平衡 调试
关闭
关闭