搜索
bottom↓
回复: 1

汇编代码调试时遇到的问题,希望给与指教,谢谢

[复制链接]

出0入0汤圆

发表于 2015-4-10 20:34:56 | 显示全部楼层 |阅读模式
关于S3C2440中一段汇编代码的疑问:
汇编代码的功能是实现上电从Nor flash中搬运4K代码到sdram中执行,调试过程中关于
存储控制器配置时使用
adr  r2, mem_cfg_val指令获取配置值存放地址,运行是正确的,
如果改成
ldr  r2,=mem_cfg_val  @存储寄存器配置值存放地址,程序无法运行
请问这两句有什么不同?
汇编代码如下:
.equ        MEM_CTL_BASE,       0x48000000
.equ        SDRAM_BASE,         0x30000000

.text
.global _start
_start:
    bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启
    bl  memsetup                        @ 设置存储控制器
    bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
    ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行
on_sdram:
    ldr sp, =0x34000000                 @ 设置堆栈
    bl  main
halt_loop:
    b   halt_loop

disable_watch_dog:
    @ 往WATCHDOG寄存器写0即可
    mov r1,     #0x53000000
    mov r2,     #0x0
    str r2,     [r1]
    mov pc,     lr      @ 返回

copy_steppingstone_to_sdram:
    @ 将Steppingstone的4K数据全部复制到SDRAM中去
    @ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
   
    mov r1, #0
    ldr r2, =SDRAM_BASE
    mov r3, #4*1024
1:  
    ldr r4, [r1],#4     @ 从Steppingstone读取4字节的数据,并让源地址加4
    str r4, [r2],#4     @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
    cmp r1, r3          @ 判断是否完成:源地址等于Steppingstone的未地址?
    bne 1b              @ 若没有复制完,继续
    mov pc,     lr      @ 返回

memsetup:
    @ 设置存储控制器以便使用SDRAM等外设

    mov r1,     #MEM_CTL_BASE       @ 存储控制器的13个寄存器的开始地址
    adr   r2, mem_cfg_val         @ 这13个值的起始存储地址
    add r3,     r1, #52             @ 13*4 = 54
1:  
    ldr r4,     [r2], #4            @ 读取设置值,并让r2加4
    str r4,     [r1], #4            @ 将此值写入寄存器,并让r1加4
    cmp r1,     r3                  @ 判断是否设置完所有13个寄存器
    bne 1b                          @ 若没有写成,继续
    mov pc,     lr                  @ 返回


.align 4
mem_cfg_val:
    @ 存储控制器13个寄存器的设置值
    .long   0x22011110      @ BWSCON
    .long   0x00000700      @ BANKCON0
    .long   0x00000700      @ BANKCON1
    .long   0x00000700      @ BANKCON2
    .long   0x00000700      @ BANKCON3  
    .long   0x00000700      @ BANKCON4
    .long   0x00000700      @ BANKCON5
    .long   0x00018005      @ BANKCON6
    .long   0x00018005      @ BANKCON7
    .long   0x008C07A3      @ REFRESH
    .long   0x000000B1      @ BANKSIZE
    .long   0x00000030      @ MRSRB6
    .long   0x00000030      @ MRSRB7

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2015-6-4 21:57:25 | 显示全部楼层
最近也在断续的学ARM,不过看的是44B0的启动代码,大同小异,关于这段汇编,以下个人理解:
adr  r2, mem_cfg_val
ADR指令是相对取址的指令,是基于PC值的,也就是说取的的地址是根据当前程序所在地址(PC)而变的(可能是Flash地址,可能是SDRAM地址,根据这段代码所处的实际物理地址而定),取址范围好像是正负4K。
ldr  r2,=mem_cfg_val
这里的LDR指令是一个伪指令,实际上实现的就是一个赋常数值指令,取得的地址是在编译时已确定的mem_cfg_val代码段所在的地址(如果编译的目标代码是运行在SDRAM里的,那这个地址就固定是在SDRAM区的一个常数),取值范围是任意32bit数。

然后在ARM里为了使代码能放在Flash里,但最后拷贝在SDRAM里运行,一般情况下是在编译时就将代码的地址就设置在SDRAM中,然后编译完下载到Flash里,在运行的时候再拷贝到编译的目标SDRAM地址处,然后实现在SDRAM里运行目标代码。研究了一下拷贝的代码,一般就是利用ADR与LDR的特性,使得代码不管在Flash里运行还是在SDRAM里运行,都能正常工作(检查代码在Flash里就先拷贝,在SDRAM里就直接运行)。

实现原理就是利用ADR的相对取值,如果在Flash里运行得到的地址就是Flash上的地址,如果在SDRAM里运行,得到的就是SDRAM里的地址;而LDR是绝对取址,得到的必定是编译的目标运行地址(SDRAM地址),以此就能判断当前代码运行在Flash还是SDRAM里,然后计算两个地址的差值并进行拷贝(一般为了速度快,也是先拷贝"拷贝代码"到SDRAM,再跳到SDRAM里的“拷贝代码"里继续拷贝其他的代码)。

sorry,跑偏了,这里的话,怀疑也是类似的原因,可能因为这段代码是编译想运行在SDRAM里的,但是却要下载到Flash里启动,因此用ADR取址就能取到正确的同在Flash里的数据地址,而用LDR却取的是SDRAM里的地址(但是看这段代码是初始化SDRAM的,也就是在复制代码之前,在这个时候SDRAM里上还没有正确数据的,甚至是还不能工作的),因此产生错误。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 21:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表