用ADS写一个ARM启动代码遇到的问题
来源:互联网 发布:爱思助手mac官方下载 编辑:程序博客网 时间:2024/05/22 06:10
今天一天我一直被一个启动代码所捆饶着:在调用一个堆栈初始化函数以后,堆栈竟然出现错误配置,指向了那些不可用的地址,导致取数据异常。一开始我以为是不是我的分散加载文件写错误了,找遍了所有的资料,都可以确认我的分散加载文件是没有问题。
这个问题是这样的:
在安装完异常向量代码以后,我调用一个Stack_init函数来实现对堆栈进行初始化。如下
start
LDR PC,RESET_ADDR
....
RESET_ADDR DCD RESET_Handler
...
RESET_Handler
BL Stack_init ;初始化堆栈,为了更好模块化,Stack_init 在另外一个文件Stack.s中实现
....
;File : Stack.S
;Author : embs
;Date : 2008/05/08
;Version : 1.0
;------------------------------------------------------------
;This File is the bootloader code for arm7,when power up.use to
; Initalization the stack of all kinds of mode
;
; you must change the size of mode that maybe use for your project
; the size of stack must align to 32bit. if not,it will data abort
;-------------------------------------------------------------------
UND_STACK_SIZE EQU 0x00000004
ABT_STACK_SIZE EQU 0x00000004
FIQ_STACK_SIZE EQU 0x00000004
IRQ_STACK_SIZE EQU 0x00000100
SVC_STACK_SIZE EQU 0x00000020
MODE_USR EQU 0x10 ;/* User Mode */
MODE_FIQ EQU 0x11 ;/* FIQ Mode */
MODE_IRQ EQU 0x12 ;/* IRQ Mode */
MODE_SVC EQU 0x13 ;/* Supervisor Mode */
MODE_ABT EQU 0x17 ;/* Abort Mode */
MODE_UND EQU 0x1B ;/* Undefined Mode */
MODE_SYS EQU 0x1F ;/* System Mode */
FIQ_MASK EQU 0x40 ;mask of IFQ ,set disable
IRQ_MASK EQU 0x80 ;mask of IRQ ,set disable
EXPORT STACK_init
CODE32
AREA Start,CODE,READONLY
STACK_init
MOV R0,LR
LDR R1,=Stack_TOP
MSR CPSR_c,#MODE_UND|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#UND_STACK_SIZE
MSR CPSR_c,#MODE_ABT|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#ABT_STACK_SIZE
MSR CPSR_c,#MODE_FIQ|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#FIQ_STACK_SIZE
MSR CPSR_c,#MODE_IRQ|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#IRQ_STACK_SIZE
MSR CPSR_c,#MODE_SVC|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#SVC_STACK_SIZE
MSR CPSR_c,#MODE_SYS|FIQ_MASK|IRQ_MASK ;default start mode
MOV SP,R1
IF :LNOT:(:DEF:START_MODE)
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
MOV PC,R0
AREA StackS,DATA,NOINIT
Stack_TOP
END
该代码反汇编以后的代码如下:
STACK_init
$a
Start
0x00000000: e1a0000e .... MOV r0,r14
0x00000004: e59f1048 H... LDR r1,0x54 <<==问题就出在这里,按理它应该加载0x00000050地址的值才对,可现在加载的0x54地址处的值。这个可以很容易与源代码比较知道
0x00000008: e321f0db ..!. MSR CPSR_c,#0xdb
0x0000000c: e1a0d001 .... MOV r13,r1
0x00000010: e2411004 ..A. SUB r1,r1,#4
0x00000014: e321f0d7 ..!. MSR CPSR_c,#0xd7
0x00000018: e1a0d001 .... MOV r13,r1
0x0000001c: e2411004 ..A. SUB r1,r1,#4
0x00000020: e321f0d1 ..!. MSR CPSR_c,#0xd1
0x00000024: e1a0d001 .... MOV r13,r1
0x00000028: e2411004 ..A. SUB r1,r1,#4
0x0000002c: e321f0d2 ..!. MSR CPSR_c,#0xd2
0x00000030: e1a0d001 .... MOV r13,r1
0x00000034: e2411f40 @.A. SUB r1,r1,#0x100
0x00000038: e321f0d3 ..!. MSR CPSR_c,#0xd3
0x0000003c: e1a0d001 .... MOV r13,r1
0x00000040: e2411020 .A. SUB r1,r1,#0x20
0x00000044: e321f0df ..!. MSR CPSR_c,#0xdf
0x00000048: e1a0d001 .... MOV r13,r1
0x0000004c: e1a0f000 .... MOV pc,r0
$d
0x00000050: 00000000 .... DCD 0 <<应该加载的地方
找了一天,花费了很多时间,终于找到了罪魁祸首:
IF :LNOT:(:DEF:START_MODE)
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
应该修改为:
IF :DEF:START_MODE
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
现在这是修改后的反汇编代码,修改好以后,也就再也不出现取数据异常了。
STACK_init
$a
Start
0x00000000: e1a0000e .... MOV r0,r14
0x00000004: e59f1044 D... LDR r1,0x50 << 0x50
0x00000008: e321f0db ..!. MSR CPSR_c,#0xdb
0x0000000c: e1a0d001 .... MOV r13,r1
0x00000010: e2411004 ..A. SUB r1,r1,#4
0x00000014: e321f0d7 ..!. MSR CPSR_c,#0xd7
0x00000018: e1a0d001 .... MOV r13,r1
0x0000001c: e2411004 ..A. SUB r1,r1,#4
0x00000020: e321f0d1 ..!. MSR CPSR_c,#0xd1
0x00000024: e1a0d001 .... MOV r13,r1
0x00000028: e2411004 ..A. SUB r1,r1,#4
0x0000002c: e321f0d2 ..!. MSR CPSR_c,#0xd2
0x00000030: e1a0d001 .... MOV r13,r1
0x00000034: e2411f40 @.A. SUB r1,r1,#0x100
0x00000038: e321f0d3 ..!. MSR CPSR_c,#0xd3
0x0000003c: e1a0d001 .... MOV r13,r1
0x00000040: e2411020 .A. SUB r1,r1,#0x20
0x00000044: e321f0df ..!. MSR CPSR_c,#0xdf
0x00000048: e1a0d001 .... MOV r13,r1
0x0000004c: e1a0f000 .... MOV pc,r0
$d
0x00000050: 00000000 .... DCD 0 <<Stack_TOP就存储在这里
所以工作必须要细心,微小的东西往往可以给人致命的打击。以后要加强修炼才行。
- 用ADS写一个ARM启动代码遇到的问题
- ARM启动代码及ADS基本使用
- ARM ADS中RO,RW和ZI的变量以及启动代码
- 用ads调试时遇到的一些问题
- 写C++代码遇到的一个问题,错误已经在代码中注释了
- 疑问:自己写代码遇到的问题
- 写struts2遇到的一个小问题
- 启动HBase后遇到的一个问题
- 太好了 今天写代码又遇到了一个新的问题
- SSH2项目启动报错(一个项目所遇到的问题,我就写一个了)
- 调试 ARM STM32 外部中断 遇到的一个问题
- 代码写Button遇到问题
- ADS安装过程中遇到cannot abtain license......的问题
- 使用ADS时候有uboot功能的启动代码
- 2440 ads启动代码的中断处理流程分析
- MFC写的一个界面遇到的问题
- 写一个简单的chorm插件和遇到的问题
- 写JAVA代码时常遇到的一些小问题
- 配置 log4j 将日志写到数据库
- ASP.NET 应用程序的扩展策略
- 我绕着Activator.CreateInstance跑
- ASP.NET中常用输出JS脚本的类(改进版)
- 用纯C#实现截取屏幕指定区域
- 用ADS写一个ARM启动代码遇到的问题
- 我的IT生涯—仿真、游戏之路
- 用AjaxPro实现无刷新翻页效果及数据库分页技术介绍
- 东华体育馆台阶
- 制作 CHM 帮助文档的最好软件 FAR HTML Help
- 用AjaxPro实现定时刷新效果
- C#接口Interface
- C#枚举类型enum
- 发送/接收数据包与发送/接收字节的区别.