对链接地址和运行时地址的理解

发布时间:2024-08-01  

1.伪指令

伪指令是写给汇编器看的,汇编器根据实际情况,将伪指令翻译成同样功能的汇编指令。


2.链接地址与运行时地址


运行时地址就是开发板在执行程序时,每条指令被读取并执行时cpu用的地址。


链接地址也是写给汇编器(链接器)看的,在链接的时候可以指定链接地址,与链接地址相关的指令在执行时使用链接地址。


3.ldr 与 adr(adrl)


其中有个举例说


   1:  adr r0, _start  

   2:  ldr r1, =_start 

上面两条指令在某些情况下得到的 _start 的值是不同的。


在这里我总结为,当链接地址与cpu上电时取第一条指令时用的地址不同时, ldr 与 adr 对同一个标号操作得到的地址不同。


其中 ldr 是根据链接地址计算 最后到的地址是   _start 标号相对于链接地址的偏移量  加上  链接地址。(可能也可以称 ldr 获取的是 _start 的链接地址?)


而adr 是根据 adr CPU执行 adr 时用的地址 加上 _start 标号相对与 adr 这条指令所在地址的偏移量。(所以说 adr 获取的是 _start 的运行时地址)


也就是说 链接地址 让编译器编译出来的指令 在跳转的时候跳与链接地址相关的指定的位置,不与当前的运行时地址相关。 


4.总结


ldr 与 adr 区别的原因是阅读 s3c2440 的一段启动代码后总结的,所以趁热记录下来方便日后记忆。


代码如下:


 1 @*************************************************************************

 2 @ File:head.S

 3 @ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

 4 @*************************************************************************       

 5  

 6 .equ        MEM_CTL_BASE,       0x48000000

 7 .equ        SDRAM_BASE,         0x30000000

 8  

 9 .text

10 .global _start

11 _start:

12     bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启

13     bl  memsetup                        @ 设置存储控制器

14     bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中

15     ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行

16 on_sdram:

17     ldr sp, =0x34000000                 @ 设置堆栈

18     bl  main

19 halt_loop:

20     b   halt_loop

21  

22 disable_watch_dog:

23     @ 往WATCHDOG寄存器写0即可

24     mov r1,     #0x53000000

25     mov r2,     #0x0

26     str r2,     [r1]

27     mov pc,     lr      @ 返回

28  

29 copy_steppingstone_to_sdram:

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

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

32     

33     mov r1, #0

34     ldr r2, =SDRAM_BASE

35     mov r3, #4*1024

36 1:  

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

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

39     cmp r1, r3          @ 判断是否完成:源地址等于Steppingstone的未地址?

40     bne 1b              @ 若没有复制完,继续

41     mov pc,     lr      @ 返回

42  

43 memsetup:

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

45  

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

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

48     add r3,     r1, #52             @ 13*4 = 54

49 1:  

50     ldr r4,     [r2], #4            @ 读取设置值,并让r2加4

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

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

53     bne 1b                          @ 若没有写成,继续

54     mov pc,     lr                  @ 返回

55  

56  

57 .align 4

58 mem_cfg_val:

59     @ 存储控制器13个寄存器的设置值

60     .long   0x22011110      @ BWSCON

61     .long   0x00000700      @ BANKCON0

62     .long   0x00000700      @ BANKCON1

63     .long   0x00000700      @ BANKCON2

64     .long   0x00000700      @ BANKCON3  

65     .long   0x00000700      @ BANKCON4

66     .long   0x00000700      @ BANKCON5

67     .long   0x00018005      @ BANKCON6

68     .long   0x00018005      @ BANKCON7

69     .long   0x008C07A3      @ REFRESH

70     .long   0x000000B1      @ BANKSIZE

71     .long   0x00000030      @ MRSRB6

72     .long   0x00000030      @ MRSRB7


在17行使用的是 ldr 而在 47行使用的是 adrl 因为上电时cpu在ram的前4k中执行指令,而在这些代码在链接的时候链接地址被人为地设置为0x30000000:


arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf


而s3c2440又将外部sdram映射到这里,所以在17行,通过 ldr 指令,虽然执行这条指令的时候并不是在 0x3000xxxx 这里,但 ldr 是根据链接地址计算将pc指向了0x30000010 ,而cpu在访问这段地址的时候又会自动产生控制信号与 sdram 交换数据,所以就达到了在sdram中执行代码的目的。


在47行的位置,此时要在ram中执行,所以要跳到 mem_cfg_val 这里时,要相对于当前的 pc 值跳转,如果使用 ldr 指令,则会跳到 0x3000xxxx 这里 ,但因为还没有将代码拷贝到 0x30000000 这里


所以程序不能正常执行。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    发送并被从机接收的信息有两类:一类是地址,用于指示需要和主机通信的从机地址,由串行数据第9位为“1”来标志;另一类是数据,由串行数据第9位为“0”来标志。 由于所有从机的SM2=1,故每个从机总能在R1=O收到主机发来的地址......
    ] = (SlaveAddr 《《 1);//准备从机地址 if ( SubMod 》 2 ) SubMod = 2;//检查子地址模式 //如果是有子地址的从机,则要先发送从机地址和子地址......
    ) return 0; //准备从机地址 a[0] = (SlaveAddr 《《 1); //检查子地址模式 if ( SubMod 》 2 ) SubMod = 2; //如果是有子地址的从机,则要先发送从机地址和子地址......
    总线忙写数据失败 主机发送I2C总线复位信号,确保写数据之前总线处于空闲状态 主机发送I2C总线开始信号,启动一次数据的写入 主机发送I2C丛机地址和写模式(W/R=0)信号,并且......
    . ipconfig 命令 如果计算机和所在的局域网使用了动态主机配置协议 DHCP,使用 ipconfig 命令可以了解到你的计算机是否成功地租用到了一个 IP 地址,如果已经租用到,则可以了解它目前得到的是什么地址......
    上的设备可以通过增长每一个时钟的低周期来降低总线时钟.所以每个主机可以适应这个设备的内部操作速率.在Hs模式,握手处理只能用在字节级别.从机地址和R/W bit下图是数据传输的格式:在开始条件(S)后,发送从机地址.地址是7bit,后面......
    协议包含四个部分: 1) 起始信号或重复起始信号的产生  2) 从机地址和R/W位传输  3) 数据传输  4) 停止信号的产生  注: S 起始信号 W/R 读/写控制位 ACK 应答 DATA 数据 P......
    就只有一个从机匹配并产生应答(A2).被主机寻址匹配的从机会保持被寻址的状态直到接收到终止条件或者是重复开始条件后跟着一个不同的从机地址. 2.主-接收器从从-发送器接收数据(10bit从地址) 在第......
    宁节表明,由用户设定地址码的从机将接收由主机发送来的信息。每个从机都有具有唯一的地址码,只有符合地址码的从机才能响应回送,且响应回送均以各自的地址码开始。主机发送的地址码则表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址......
    于对端与本地Mac地址的处理。 以太网第三层是网络层。每一台搭载了以太网的ECU都需要定义ip地址主机的网络地址该如何定义,以及如何在网络地址和MAC地址之间进行映射,即ARP协议;网络......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>