打印

LDR PC, # 不会跳转,而是顺序执行下一行的问题?

[复制链接]
8041|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
云痕|  楼主 | 2008-7-11 10:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
pc, AC, ST, ck, Stack
我用的ADS1.2+ H-JTAG调试的LPC2364,AXD仿真的时候,
Vectors         LDR     PC, Reset_Addr         ;0
                LDR     PC, Undef_Addr         ;4
                LDR     PC, SWI_Addr           ;8
                LDR     PC, PAbt_Addr          ;c
                LDR     PC, DAbt_Addr          ;10
                NOP                            ;14 Reserved Vector 

从Vectors行开始单步执行,LDR     PC, Reset_Addr 执行之后不是跳转,而是顺序执行LDR     PC, Undef_Addr,后面也全部相同,从Regisers窗口观察Current里的pc值,和指令相对应,00>04>08>0c。之前还有遇到就是进入main()后,一部分函数执行完毕后,继续执行剩下的函数,结果到函数返回的‘}’后,有时候跳到数据或指令异常,或跳到main()后紧跟的那个'{'行首,感觉很怪异,想不出什么解决办法,感觉和启动代码,或者scatter文件相关。
启动代码:
    PRESERVE8
    
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs

Mode_USR        EQU     0x10
Mode_FIQ        EQU     0x11
Mode_IRQ        EQU     0x12
Mode_SVC        EQU     0x13
Mode_ABT        EQU     0x17
Mode_UND        EQU     0x1B
Mode_SYS        EQU     0x1F

I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled

;// <h> Stack Configuration (Stack Sizes in Bytes)
;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8> 
;// </h>

;定义堆栈的大小,最终工作在系统模式,栈名StackUsr,只给了起始位置,未指定大小
SVC_STACK_LEGTH         EQU         0        ;单位为字
FIQ_STACK_LEGTH         EQU         0
IRQ_STACK_LEGTH         EQU         512
ABT_STACK_LEGTH         EQU         0
UND_STACK_LEGTH         EQU         0

;USR_STACK_LEGTH         EQU         1024  ;设定用户模式栈

Heap_Size       EQU     1024

    IMPORT __use_no_semihosting_swi
    IMPORT __use_two_region_memory

    IMPORT    TargetResetInit
    IMPORT  FIQ_Exception
    IMPORT  __main
                
;The emported labels
;给外部使用的标号在这声明
;    EXPORT  bottom_of_heap
    EXPORT  bottom_of_Stacks
;    EXPORT  top_of_heap
    EXPORT  StackUsr    
    EXPORT  Reset_Handler
    EXPORT __user_initial_stackheap
    
; Area Definition and Entry Point
;  Startup Code must be linked first at Address at which it expects to run.

                CODE32
                AREA    RESET, CODE, READONLY
                ENTRY

; Exception Vectors
;  Mapped to Address 0.
;  Absolute addressing mode must be used.
;  Dummy Handlers are implemented as infinite loops which can be modified.

Vectors         LDR     PC, Reset_Addr         ;0
                LDR     PC, Undef_Addr         ;4
                LDR     PC, SWI_Addr           ;8
                LDR     PC, PAbt_Addr          ;c
                LDR     PC, DAbt_Addr          ;10
                NOP                            ;14 Reserved Vector 
              ;LDR     PC, IRQ_Addr             
                LDR     PC, [PC, #-0x0120]     ;18  Vector from VicVectAddr
                LDR     PC, FIQ_Addr           ;1c

Reset_Addr      DCD     Reset_Handler          ;20
Undef_Addr      DCD     Undef_Handler          ;24
SWI_Addr        DCD     SWI_Handler            ;28
PAbt_Addr       DCD     PAbt_Handler           ;2c
DAbt_Addr       DCD     DAbt_Handler           ;20
                DCD     0xB9206E28             ;34 Reserved Address 
IRQ_Addr        DCD     IRQ_Handler            ;38
FIQ_Addr        DCD     FIQ_Handler            ;3c

Undef_Handler   B       Undef_Handler          ;40
SWI_Handler     B       SWI_Handler            ;44
PAbt_Handler    B       PAbt_Handler           ;48
DAbt_Handler    B       DAbt_Handler           ;4c 
IRQ_Handler     B       IRQ_Handler            ;40
FIQ_Handler     B       FIQ_Handler            ;44       
                
Reset_Handler   
;  Enter Undefined Instruction Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
                LDR     SP, StackUnd

;  Enter Abort Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
                LDR     SP, StackAbt

;  Enter FIQ Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
                LDR     SP, StackFiq

;  Enter IRQ Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
                LDR     SP, StackIrq

;  Enter Supervisor Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
                LDR     SP, StackSvc

;  Enter Sys Mode and set its Stack Pointer
;                MSR     CPSR_c, #Mode_SYS:OR:I_Bit:OR:F_Bit
;                LDR     SP, StackSys

;  Enter User Mode and set its Stack Pointer
;                MSR     CPSR_c, #Mode_USR 
                 MSR     CPSR_c, #Mode_SYS:OR:F_Bit
                 LDR     SP, =StackUsr
                
                BL        TargetResetInit 
; Enter the C code
                LDR     R0, =__main
                BX      R0
;                B       __main

;// <h> Heap Configuration
;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>

; User Initial Stack & Heap
;                AREA    |.text|, CODE, READONLY
__user_initial_stackheap     
    LDR   R0,=bottom_of_heap              ;heap基地址
    LDR   r1,=StackUsr                    ;栈基地址
    LDR   r2,=top_of_heap                 ;heap长度限制值
    LDR   r3,=bottom_of_Stacks            ;栈长度限制值
    MOV   pc,lr
    
StackSvc           DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq           DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt           DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd           DCD     UndStackSpace + (UND_STACK_LEGTH - 1)* 4

    IF :DEF: EN_CRP
        IF  . >= 0x1fc
        INFO    1,"\nThe data at 0x000001fc must be 0x87654321.\nPlease delete some source before this line."
        ENDIF
CrpData
    WHILE . < 0x1fc
    NOP
    WEND
CrpData1
    DCD     0x87654321          ;/*When the Data is 为0x87654321,user code be protected. 当此数为0x87654321时,用户程序被保护 */
    ENDIF
    
;/* 分配堆栈空间 */
        AREA    MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;Stack spaces for Administration Mode 管理模式堆栈空间
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;Stack spaces for Interrupt ReQuest Mode 中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;Stack spaces for Fast Interrupt reQuest Mode 快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;Stack spaces for Suspend Mode 中止义模式堆栈空间
UndStackSpace      SPACE   UND_STACK_LEGTH * 4  ;Stack spaces for Undefined Mode 未定义模式堆栈

        AREA    Heap, DATA, NOINIT, ALIGN=3
bottom_of_heap    SPACE   1

        AREA    StackBottom, DATA, NOINIT, ALIGN=3
bottom_of_Stacks    SPACE   1

        AREA    HeapTop, DATA, NOINIT, ALIGN=3
top_of_heap    SPACE   1  

         AREA    Stacks, DATA, NOINIT, ALIGN=3
StackUsr        SPACE   1  

         END

scatter文件:
ROM_LOAD 0x0
{
    ROM_EXEC 0x0
    {
        Startup_a.o (RESET, +First)
        * (+RO)
    }

    ERAM 0x40000000 UNINIT
    {
        * (+RW,+ZI)
    } 
    
    MYSTACKS +0 UNINIT
    {
        Startup_a.o (MyStacks)
    } 

    HEAP +0 UNINIT           
    {
        Startup_a.o (Heap)
    }
 
    HEAP_BOTTOM +256 UNINIT  
    {
        Startup_a.o (HeapTop)
    }
 
    USERSTACKS +0 UNINIT
    {
       Startup_a.o (StackBottom)
    } 
    
    STACKS_BOTTOM 0x40002000 UNINIT   ;//LPC2364
    {
      Startup_a.o (Stacks)
    } 
}

启动代码和scatter文件都是仿照ZLG2200模板写的。

相关帖子

沙发
sxggj| | 2008-7-11 10:42 | 只看该作者

感觉应该跟LDR和B有关,试着改成B试试

而且是不是用LDR时后面的操作数加=

使用特权

评论回复
板凳
云痕|  楼主 | 2008-7-11 11:14 | 只看该作者

应该不是这个问题

启动跳转这写代码,参照了ZLG和优龙的,都是这样的。而且该跳不跳,也不是一直发生。之前发生过,后来莫名其妙没这问题了,现在又出现了的

使用特权

评论回复
地板
sxggj| | 2008-7-11 11:21 | 只看该作者

开头就是一个跳转指令,你直接跳不就得了,整的这么麻烦

使用特权

评论回复
5
云痕|  楼主 | 2008-7-11 13:32 | 只看该作者

开头已经就是个跳转啊LDR PC, Reset_Addr

sxggj 发表于 2008-7-11 11:21 ARM 论坛 ←返回版面    

4楼: 开头就是一个跳转指令,你直接跳不就得了,整的这么麻烦 

开头已经就是跳转啊,LDR   PC, Reset_Addr 之前都是一些声明而已。仿真时,加载后箭头就是在这行行首的。只是执行起来不是跳转,而是顺序罢了

使用特权

评论回复
6
云痕|  楼主 | 2008-7-11 13:53 | 只看该作者

换了一块板子试试,还是如此

使用特权

评论回复
7
sxggj| | 2008-7-11 14:21 | 只看该作者

我也是初学者

不过觉得你最好开头直接用个B命令跳到该跳的地方,不一定所有的仿真器都能在开头用LDR命令

使用特权

评论回复
8
bald| | 2008-7-11 14:26 | 只看该作者

可能是程序载入错误

打开 Interleave Disassebly 看看,反汇编程序和原程序肯定不一样。

也可以用 ARMUL 仿真一下看看,如果没问题有可能是硬件问题
可能原因有:
内存地址配置
BMS 设置
REMAP
仿真器启动了MMU而页表没有载入

使用特权

评论回复
9
sxggj| | 2008-7-11 14:32 | 只看该作者

还有你的DCD指令用法对吗???????

使用特权

评论回复
10
云痕|  楼主 | 2008-7-13 18:17 | 只看该作者

贴下汇编代码

Reset    [0xe59ff018]   ldr      pc,ResetAddr ; = #ResetAddr
00000004    [0xe59ff018]   ldr      pc,UndefinedAddr ; = #UndefinedAddr
00000008    [0xe59ff018]   ldr      pc,SWI_Addr ; = #SWI_Addr
0000000c    [0xe59ff018]   ldr      pc,PrefetchAddr ; = #PrefetchAddr
00000010    [0xe59ff018]   ldr      pc,DataAbortAddr ; = #DataAbortAddr
00000014    [0xb8a06f58]   dcd      0xb8a06f58  Xo..
00000018    [0xe59ff018]   ldr      pc,IRQ_Addr ; = #IRQ_Addr
0000001c    [0xe59ff018]   ldr      pc,FIQ_Addr ; = #FIQ_Addr

ResetAddr    [0x00001548]   dcd      0x00001548  H...
UndefinedAddr    [0x00001414]   dcd      0x00001414  ....
SWI_Addr    [0x00001418]   dcd      0x00001418  ....
。。
ResetInit    [0x2001fb77]   andcs    pc,r1,r7,ror r11
。。

InitStack
        0x000000c0:    e1a0000e    ....    MOV      r0,r14      
从汇编代码看,ldr      pc,ResetAddr ; 加载ResetAddr 标号地址内容,此标号地址存放的是指令dcd      0x00001548 ,pc直接跳转0x00001548,实际仿真结果也是这样
但源码中, 
LDR PC, ResetAddr 
 。。
ResetAddr     DCD ResetInit 
。。
ResetInit   BL InitStack ;初始化堆栈 Initialize the stack 
感觉汇编和源码不对应。然后把projiect_data文件夹删除了,然后重新编译,还是如此。

AXD改ARMUL模式脱离硬件调试时,调用的是同一个.axf文件,跳转是正确的,
在ARMUL模式下,ResetAddr    [0x000000f8]   dcd      0x000000f8  ...这条指令和H-JTAG下的汇编指令不同.,弄不明白。可不可能是JTAG头的问题?

使用特权

评论回复
11
云痕|  楼主 | 2008-7-13 20:22 | 只看该作者

LPC2364片内没MMU的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

75

帖子

0

粉丝