C代码中如何使用链接脚本中定义的变量

本文详细解释了在C语言中如何引用链接脚本定义的BSS段起始和结束地址,以及为什么在C代码中需要使用取址运算符。通过对比变量声明与链接脚本中的值定义,阐述了符号表的作用及取址符号的重要性。

转载地址:https://blog.youkuaiyun.com/czg13548930186/article/details/78535419

原文内容:http://www.100ask.org/bbs/forum.php?mod=viewthread&tid=16231&page=1&authorid=2

--------------------------------------------------------------------------------------------------------------------------

参考文章:https://sourceware.org/ml/binutils/2007-07/msg00154.html


在链接脚本中,经常有这样的代码:
SECTIONS
{
       .....
        . = ALIGN(4);
        .rodata : { *(.rodata) }

        . = ALIGN(4);
        .data : { *(.data) }

        . = ALIGN(4);
        .got : { *(.got) }

        . = ALIGN(4);
        __bss_start = .;
        .bss : { *(.bss) }
        _end = .;
}
复制代码

其中__bss_start, _end 表示BSS段的起始、终止地址。
我们想对这段空间清零时,
1.在汇编代码中,可以直接引用__bss_start,  _end,比如:
ldr r0, =__bss_start
ldr r1, =_end
复制代码

2.  在C代码中,我们不能直接引用它们,要这样做:
void clean_bss(void)
{
    extern int __bss_start, _end;
    int *p = &__bss_start;
    
    for (; p < &_end; p++)
        *p = 0;
}
复制代码

__bss_start, _end不是表示某个值吗?在C代码中为什么要使用取址符号 & ?

原因:
一. 
在C代码中,这样的语句:
int foo = 1000;
复制代码
会导致2件事情发生:
1.  在代码中,留出4字节的空间,保存数值1000
2.在C语言的symbole talbe,即符号表中,有一个名为foo的项,它里面存有那4字节空间的地址。

我们执行 foo = 1时,会先去符号表中找到foo对应的地址,然后把数值1填到那个地址对应的内存;
我们执行 int *a = &foo时,会直接把符号表中foo的地址,写给a。

二.
在链接脚本中,假设
__bss_start = 1000
复制代码

__bss_start并不是一个变量,它只是一个值,并不需要在内存中留出一段空间来保存它;
在C语言中,符号表中会有一个名为__bss_start的项,这个项目中的值(地址值)是1000;
注意,这个1000并没有实际存在的内存。

三.
所以:在C语言中,要去使用链接脚本中定义的值时,应该这样做:
extern int __bss_start;
int val = &__bss_start;
复制代码
使用取址符号&去得到它在符号表中的值。


--------------------- 
作者:种瓜大爷 
来源:优快云 
原文:https://blog.youkuaiyun.com/czg13548930186/article/details/78535419?utm_source=copy 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值