使用ldr命令注意事项
来源:互联网 发布:淘宝直播申请不过 编辑:程序博客网 时间:2024/06/06 01:25
今天犯了一个小错误,调试了几个小时;最后重新分析了几遍反汇编才发现。万丈高楼平地起、勿以浮沙驻高台。
错误代码:
.text.global _start_start: b reset ldr pc,=und_addr ldr pc,=swi_addrund_addr: .word undefswi_addr: .word swi_handleundef: 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 4swi_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_nextsdram_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-littlearmDisassembly of section .text:30000000 <_start>:30000000: ea00001e b 30000080 <reset>30000004: e59ff110 ldr pc, [pc, #272] ; 3000011c <.text+0x11c>30000008: e59ff110 ldr pc, [pc, #272] ; 30000120 <.text+0x120>3000000c <und_addr>:3000000c: 30000014 andcc r0, r0, r4, lsl r030000010 <swi_addr>:30000010: 30000050 andcc r0, r0, r0, asr r0*************************************************3000011c: 3000000c andcc r0, r0, ip30000120: 30000010 andcc r0, r0, r0, lsl r0*************************************************30000014 <undef>:30000014: e3a0d432 mov sp, #838860800 ; 0x3200000030000018: e92d5fff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}3000001c: eb000103 bl 30000430 <print2>30000020: e10f0000 mrs r0, CPSR30000024: e59f10f8 ldr r1, [pc, #248] ; 30000124 <.text+0x124>30000028: eb000216 bl 30000888 <printException>3000002c: e8fd9fff ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^30000030 <und_string>: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-littlearmDisassembly of section .text:***************************************3000011c: 30000014 andcc r0, r0, r4, lsl r030000120: 30000050 andcc r0, r0, r0, asr r0***************************************30000000 <_start>:30000000: ea00001e b 30000080 <reset>30000004: e59ff110 ldr pc, [pc, #272] ; 3000011c <.text+0x11c>30000008: e59ff110 ldr pc, [pc, #272] ; 30000120 <.text+0x120>3000000c <und_addr>:3000000c: 30000014 andcc r0, r0, r4, lsl r030000010 <swi_addr>:30000010: 30000050 andcc r0, r0, r0, asr r030000014 <undef>:30000014: e3a0d432 mov sp, #838860800 ; 0x3200000030000018: e92d5fff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}3000001c: eb000103 bl 30000430 <print2>30000020: e10f0000 mrs r0, CPSR30000024: e59f10f8 ldr r1, [pc, #248] ; 30000124 <.text+0x124>30000028: eb000216 bl 30000888 <printException>3000002c: e8fd9fff ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^30000030 <und_string>:...30000050 <swi_handle>: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-littlearmDisassembly of section .text:30000000 <_start>:30000000: ea00001e b 30000080 <reset>30000004: e59ff110 ldr pc, [pc, #272] ; 3000011c <.text+0x11c>30000008: e59ff110 ldr pc, [pc, #272] ; 30000120 <.text+0x120>*********************3000011c: 30000014 andcc r0, r0, r4, lsl r030000120: 30000050 andcc r0, r0, r0, asr r0*********************3000000c <und_addr>:3000000c: 30000014 andcc r0, r0, r4, lsl r030000010 <swi_addr>:30000010: 30000050 andcc r0, r0, r0, asr r030000014 <undef>:30000014: e3a0d432 mov sp, #838860800 ; 0x3200000030000018: e92d5fff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}3000001c: eb000103 bl 30000430 <print2>30000020: e10f0000 mrs r0, CPSR30000024: e59f10f8 ldr r1, [pc, #248] ; 30000124 <.text+0x124>30000028: eb000216 bl 30000888 <printException>3000002c: e8fd9fff ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^30000030 <und_string>:...30000050 <swi_handle>:30000050: e3a0d433 mov sp, #855638016 ; 0x33000000...
结果:
总结:
注意ldr pc,=czg
与ldr pc,czg
用法:
① ldr pc,=czg
=》 pc = czg (就是czg标号的地址)
② ldr pc,czg
=》 pc = *(czg) (czg标号地址中放的值)
阅读全文
1 0
- 使用ldr命令注意事项
- 使用nohup命令注意事项
- 使用命令提示符注意事项
- 关于LDR命令
- 汇编LDR使用学习
- 使用SC命令时注意事项
- ldr
- LDR
- ldr
- centos 使用网络管理命令注意事项
- fsck命令使用详解及特别注意事项
- adr adrl ldr伪指令的使用
- adr adrl ldr伪指令的使用
- adr adrl ldr伪指令的使用
- 模块-内核模块加载命令modprobe使用注意事项
- oracle数据库的导出 exp命令使用注意事项
- 使用MySQL MySqldump命令导出数据时的注意事项,mysqlmysqldump
- 使用git命令操作github时的一些注意事项
- Codeforces Round #443 (Div. 1) C. Tournament
- 改变checkbox大小
- 对于向下转型,变量是否也会向下转型
- 《锋利的jQuery》读书笔记第三章(DOM操作)
- linux防毒软件
- 使用ldr命令注意事项
- [POJ](3614)Sunscreen ---- 优先级队列+贪心
- smartsvn基本操作
- 蓝桥杯 算法训练 关联矩阵
- 输入某年的第几天,计算并输出它是这一年的第几月第几日
- spring注解开发AnnotationConfigApplicationContext的使用
- 又到年底了,你的拖延症治愈了吗
- CODEVS 1023 C++ 青铜
- js设置li高度与前面内容同高