链接地址和运行地址.docx

上传人:b****6 文档编号:6170601 上传时间:2023-01-04 格式:DOCX 页数:11 大小:21.33KB
下载 相关 举报
链接地址和运行地址.docx_第1页
第1页 / 共11页
链接地址和运行地址.docx_第2页
第2页 / 共11页
链接地址和运行地址.docx_第3页
第3页 / 共11页
链接地址和运行地址.docx_第4页
第4页 / 共11页
链接地址和运行地址.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

链接地址和运行地址.docx

《链接地址和运行地址.docx》由会员分享,可在线阅读,更多相关《链接地址和运行地址.docx(11页珍藏版)》请在冰豆网上搜索。

链接地址和运行地址.docx

链接地址和运行地址

1、运行地址<--->链接地址:

他们两个是等价的,只是两种不同的说法。

2、加载地址<--->存储地址:

他们两个是等价的,也是两种不同的说法。

运行地址:

程序在SRAM、SDRAM中执行时的地址。

就是执行这条指令时,PC应该等于这个地址,换句话说,PC等于这个地址时,这条指令应该保存在这个地址内。

加载地址:

程序保存在Nandflash中的地址。

位置无关码:

B、BL、MOV都是位置位置无关码。

位置有关码:

LDRPC,=LABEL等类似的代码都是位置有关码。

 

下面我们来看看一个Makefile文件

sdram.bin:

head.S leds.c

   arm-linux-gcc -c-ohead.ohead.S

   arm-linux-gcc-c-oleds.oleds.c

   arm-linux-ld-Ttext0x30000000head.oleds.o-osdram_elf

   arm-linux-objcopy-Obinary-Ssdram_elfsdram.bin

   arm-linux-objdump-D-marm sdram_elf>sdram.dis

clean:

 rm-f  sdram.dissdram.binsdram_elf*.o

 我们可以看到sdram_elf的代码段是从0x30000000地址开始存放,这个地址我们称之为运行地址。

为什么从这个地址开始存放,因为SDRAM的起始地址是0x30000000.

下面来看看一个启动代码@*************************************************************************

@File:

head.S

@功能:

设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

@*************************************************************************  

.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中

    ldrpc,=on_sdram                   @跳到SDRAM中继续执行

on_sdram:

   ldrsp,=0x34000000                @设置堆栈

   bl main

halt_loop:

   b  halt_loop

disable_watch_dog:

   @往WATCHDOG寄存器写0即可

   movr1,    #0x53000000

   movr2,    #0x0

   strr2,    [r1]

   movpc,    lr     @返回

copy_steppingstone_to_sdram:

   @将Steppingstone的4K数据全部复制到SDRAM中去

   @Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000

    

   movr1,#0

   ldrr2,=SDRAM_BASE

   movr3,#4*1024

1:

  

   ldrr4,[r1],#4    @从Steppingstone读取4字节的数据,并让源地址加4

   strr4,[r2],#4    @将此4字节的数据复制到SDRAM中,并让目地地址加4

   cmpr1,r3         @判断是否完成:

源地址等于Steppingstone的未地址?

   bne1b             @若没有复制完,继续

   movpc,    lr     @返回

memsetup:

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

   movr1,    #MEM_CTL_BASE      @存储控制器的13个寄存器的开始地址

   adrl   r2,mem_cfg_val        @这13个值的起始存储地址

   addr3,    r1,#52            @13*4=54

1:

  

   ldrr4,    [r2],#4           @读取设置值,并让r2加4

   strr4,    [r1],#4           @将此值写入寄存器,并让r1加4

   cmpr1,    r3                 @判断是否设置完所有13个寄存器

   bne1b                         @若没有写成,继续

   movpc,    lr                 @返回

.align4

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

下面来看看反汇编代码

sdram_elf:

    fileformatelf32-littlearm

Disassemblyofsection.text:

30000000<_start>:

30000000:

   eb000005   bl   3000001c

30000004:

   eb000010   bl   3000004c

30000008:

   eb000007   bl   3000002c

3000000c:

   e59ff090   ldr   pc,[pc,#144]   ;300000a4

30000010:

30000010:

   e3a0d30d   mov   sp,#872415232   ;0x34000000

30000014:

   eb000033   bl   300000e8

30000018:

30000018:

   eafffffe   b   30000018

3000001c:

3000001c:

   e3a01453   mov   r1,#1392508928   ;0x53000000

30000020:

   e3a02000   mov   r2,#0

30000024:

   e5812000   str   r2,[r1]

30000028:

   e1a0f00e   mov   pc,lr

3000002c:

3000002c:

   e3a01000   mov   r1,#0

30000030:

   e3a02203   mov   r2,#805306368   ;0x30000000

30000034:

   e3a03a01   mov   r3,#4096   ;0x1000

30000038:

   e4914004   ldr   r4,[r1],#4

3000003c:

   e4824004   str   r4,[r2],#4

30000040:

   e1510003   cmp   r1,r3

30000044:

   1afffffb   bne   30000038

30000048:

   e1a0f00e   mov   pc,lr

3000004c:

3000004c:

   e3a01312   mov   r1,#1207959552   ;0x48000000

30000050:

   e28f2018   add   r2,pc,#24

30000054:

   e1a00000   nop         ;(movr0,r0)

30000058:

   e2813034   add   r3,r1,#52   ;0x34

3000005c:

   e4924004   ldr   r4,[r2],#4

30000060:

   e4814004   str   r4,[r1],#4

30000064:

   e1510003   cmp   r1,r3

30000068:

   1afffffb   bne   3000005c

3000006c:

   e1a0f00e   mov   pc,lr

30000070:

30000070:

   22011110   andcs   r1,r1,#4

30000074:

   00000700   andeq   r0,r0,r0,lsl#14

30000078:

   00000700   andeq   r0,r0,r0,lsl#14

3000007c:

   00000700   andeq   r0,r0,r0,lsl#14

30000080:

   00000700   andeq   r0,r0,r0,lsl#14

30000084:

   00000700   andeq   r0,r0,r0,lsl#14

30000088:

   00000700   andeq   r0,r0,r0,lsl#14

3000008c:

   00018005   andeq   r8,r1,r5

30000090:

   00018005   andeq   r8,r1,r5

30000094:

   008c07a3   addeq   r0,ip,r3,lsr#15

30000098:

   000000b1   strheq   r0,[r0],-r1

3000009c:

   00000030   andeq   r0,r0,r0,lsrr0

300000a0:

   00000030   andeq   r0,r0,r0,lsrr0

300000a4:

   30000010    andcc   r0,r0,r0,lslr0

300000a8:

   e1a00000   nop         ;(movr0,r0)

300000ac:

   e1a00000   nop         ;(movr0,r0)

300000b0:

300000b0:

   e52db004   push   {fp}      ;(strfp,[sp,#-4]!

300000b4:

   e28db000   add   fp,sp,#0

300000b8:

   e24dd00c   sub   sp,sp,#12

300000bc:

   e50b0008   str   r0,[fp,#-8]

300000c0:

   ea000002   b   300000d0

300000c4:

   e51b3008   ldr   r3,[fp,#-8]

300000c8:

   e2433001   sub   r3,r3,#1

300000cc:

   e50b3008   str   r3,[fp,#-8]

300000d0:

   e51b3008   ldr   r3,[fp,#-8]

300000d4:

   e3530000   cmp   r3,#0

300000d8:

   1afffff9   bne   300000c4

300000dc:

   e28bd000   add   sp,fp,#0

300000e0:

   e8bd0800   pop   {fp}

300000e4:

   e12fff1e   bx   lr

300000e8

:

300000e8:

   e92d4800   push   {fp,lr}

300000ec:

   e28db004   add   fp,sp,#4

300000f0:

   e24dd008   sub   sp,sp,#8

300000f4:

   e3a03000   mov   r3,#0

300000f8:

   e50b3008   str   r3,[fp,#-8]

300000fc:

   e59f3030   ldr   r3,[pc,#48]   ;30000134

30000100:

   e3a02b55   mov   r2,#87040   ;0x15400

30000104:

   e5832000   str   r2,[r3]

30000108:

   e59f0028   ldr   r0,[pc,#40]   ;30000138

3000010c:

   ebffffe7   bl   300000b0

30000110:

   e59f3024   ldr   r3,[pc,#36]   ;3000013c

30000114:

   e3a02000   mov   r2,#0

30000118:

   e5832000   str   r2,[r3]

3000011c:

   e59f0014   ldr   r0,[pc,#20]   ;30000138

30000120:

   ebffffe2   bl   300000b0

30000124:

   e59f3010   ldr   r3,[pc,#16]   ;3000013c

30000128:

   e3a02e1e   mov   r2,#480   ;0x1e0

3000012c:

   e5832000   str   r2,[r3]

30000130:

   eafffff4   b   30000108

30000134:

   56000010   undefinedinstruction0x56000010

30000138:

   00007530   andeq   r7,r0,r0,lsrr5

3000013c:

   56000014   undefinedinstruction0x56000014

Disassemblyofsection.ARM.attributes:

00000000<.ARM.attributes>:

  0:

   00002541   andeq   r2,r0,r1,asr#10

  4:

   61656100   cmnvs   r5,r0,lsl#2

  8:

   01006962   tsteq   r0,r2,ror#18

  c:

   0000001b   andeq   r0,r0,fp,lslr0

 10:

   00543405   subseq   r3,r4,r5,lsl#8

 14:

   01080206   tsteq   r8,r6,lsl#4

 18:

   04120109   ldreq   r0,[r2],#-265   ;0x109

 1c:

   01150114   tsteq   r5,r4,lslr1

 20:

   01180317   tsteq   r8,r7,lslr3

 24:

   Address0x00000024isoutofbounds.

Disassemblyofsection.comment:

00000000<.comment>:

  0:

   3a434347   bcc   10d0d24

  4:

   74632820   strbtvc   r2,[r3],#-2080   ;0x820

  8:

   312d676e   teqcc   sp,lr,ror#14

  c:

   312e362e   teqcc   lr,lr,lsr#12

 10:

   2e342029   cdpcs   0,3,cr2,cr4,cr9,{1}

 14:

   00332e34   eorseq   r2,r3,r4,lsrlr

当我们从Nandflash启动时,硬件会自动将Nandflash前4kB代码拷贝到片内SRAM中,然后CPU从SRAM的0x00000000地址处开始执行程序。

在这里我想纠正一个错误的观点,网上很多人都说是CPU自动把Nandflash前4kB代码拷贝到片内SRAM中,其实不然,是Nandflash控制器完成的,这个过程中CPU根本就没有参与。

通过上面的Makefile文件,我们可以知道bl disable_watch_dog   这条指令的运行地址是0x30000000,但是它现在保存在SRAM的0x00000000的地址处,那么这条指令能够正确执行吗?

ofcourse,why?

因为这条指令 bl disable_watch_dog   是位置无关码,虽然它的运行地址是在SDRAM中的0x30000000,但是它可以在Steppingstone中执行。

这条指令的功能是跳转到标号disable_watch_dog处执行,它是一个相对跳转,PC=当前PC的值+偏移量OFFSET。

其中当前PC的值等于下两条指令的地址,通过反汇编可以看到下两条指令的地址为0x00000008,而不是0x30000008.因为现在指令是保存在SRAM中。

这条指令的机器码为eb000005,将机器码低24位按符号位扩展成32位得到0x000000005.然后将0x00000005左移2位得到0x00000014。

这个值就是偏移量OFFSET=0X00000014。

所以PC=0X00000008+0X00000014=0X0000001c.那么CPU就会到SRAM中的0x0000001c地址处执行程序。

可以发现bl指令依赖当前PC的值,这个特性使得bl指令不依赖指令的运行地址。

所以接下来的blmensetup,blcope_steppingstone_to_sdram都能够执行。

接下来的ldrpc,=on_sdram是一条位置有关码,经过反汇编可以看到,它是当前pc的值+偏移量,得到一个地址Addr,然后从内存中的这个地址去取数据Data赋给pc。

现在我们计算一下Addr这个地址。

Addr=当前PC的值+144。

当前PC的值等于下两条指令的地址0x00000014,而不是0x30000014,因为现在程序是保存在SRAM中。

所以Addr=0x00000014+144=0x00000014+0x00000090=0x000000a4.那么这个地址0x000000a4中保存了什么数据。

通过反汇编可以看到SRAM中的0x000000a4这个地址保存的机器码为30000010,所以cpu会跳转到0x30000010这个地址处执行程序。

这个地址0x30000010

是在SDRAM中,这样程序就跳到SDRAM中去了。

因为我们前面的指令blcope_stepping_to_sdram已经把SRAM中4kB的程序拷贝到了SDRAM中,所以现在SDRAM中有程序了。

 

但是如果在程序的开头放置一条这样的指令:

ldrpc,=disable_watch_dog,那么整个程序就不能够正确执行了。

why?

我们先来看看启动代码

@*************************************************************************

@File:

head.S

@功能:

设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

@**

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1