1.4.3重定位_使用C语言清除BSS段

使用C语言清除BSS段,我们肯定要获取BSS段的起始地址和结束地址,那么,C语言要怎么实现使用lds文件中的变量abc?

答:需要以下两步,这两步是重点

  1. 在函数中声明该变量为extern类型(类型不重要,因为我们主要是取值,具体原因后面会说);
  2. 使用时,要取址,比如, int *p = &abc;//p的值即为lds中abc的值。

比如下图中,使用extern声明代码段的起始地址和bss段的起始地址,然后取值用指针进行复制操作,这样lds中的变量也可以像C语言中的普通变量一样操作。(实际上,它们和C语言中的变量不同。
在这里插入图片描述
在C语言中需要声明,那么在汇编指令中,为什么可以直接使用?(如下图,为重定位和清除bss段的汇编代码)
在这里插入图片描述
下面开始解答:
在C函数中,如果我们声明如下变量。这样,该变量为全局变量:

int g_i;	//程序中必然有四字节空间来保存这个变量

但是,如果我们在lds链接文件中声明了a1,a2,a3…an个变量,那么,.bin文件中是不会保存这些变量的,这是为啥?

答:这是因为C程序中不保存lds文件中的变量(因为一般用不到),而且真正要用到的时候,我们也并不是没办法。

我们编译程序时,有一个symbol table符号表,万一要用这些变量,可以通过这个符号表在链接的时候使用。

以上面为例,除了g_i,我们再声明两个变量:

int g_i, g_j, g_k;	

那么在链接的时候,会有一个符号表如下:
在这里插入图片描述
画质不好,但是还是能看懂的。这里每个圈表示一个变量,一个变量由名字和地址构成。显然,C语言中的变量,名字即为变量名,地址即为变量的地址。但是,我们前面说过,.bin文件中不会保存lds文件中的变量,所以lds文件中的变量,地址填的是值,名字则还是变量名。 所以,我们在copy2sdram函数中才要使用取址符号来修饰这个lds变量,因为它的地址才是它的值。

另外,我们要明白。

  1. 这个符号表只存在于链接时,作用是辅助链接,不存在与.bin文件中。
  2. lds文件中,无论变量还是常量,里面的值都来自于链接脚本,在链接时由编译器决定。

在使用上,他们和C语言中的普通变量是不同的:

  1. 对于g_i,它是一个C语言变量,使用&g_i就可以得到它的地址Addr;
  2. 对于lds中的a1,他们没有地址,因为.bin文件里面不会保存它们,C语言中使用它们时,使用&a1取它们的值。

综上所述,使用ld中的变量,就是借助symbol table保存lds的变量,使用时加上&得到它们的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值