zoukankan      html  css  js  c++  java
  • 【转】C代码使用链接脚本定义的变量

    转载自:http://bbs.100ask.org/forum.php?mod=viewthread&tid=16231


    在链接脚本中,经常有这样的代码:

    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;
    

    使用取址符号&去得到它在符号表中的值。

    注意,这个值只是链接脚本中定义的值,并不表示某个变量的地址。

  • 相关阅读:
    [BZOJ 4001] [TJOI 2015] 概率论
    【计算几何】推导坐标的旋转公式
    【动态规划学习】01背包
    (坑)网络流24题
    bzoj2442(单调队列优化)
    [lydsy2005]能量采集
    主席树
    [noi2005][treap]序列维护
    [Apio2012][Treap]派遣
    [CodeVs][1514][Treap][书架]
  • 原文地址:https://www.cnblogs.com/bluettt/p/15338237.html
Copyright © 2011-2022 走看看