Lou*_*uis 6 c linux memory x86 assembly
首先:我知道有很多网页(包括 stackoverflow 上的讨论)讨论了数据声明之间的差异.bss和数据声明的差异,但我有一个具体的问题,不幸的是我没有在这些页面上找到答案,.data所以我在这里问:-)。
我是汇编方面的大初学者,所以如果问题很愚蠢,我深表歉意:-)。
我正在 x86 64 位 Linux 操作系统上学习汇编,但我认为我的问题更笼统,可能不特定于操作系统/架构。
.bss我发现和部分的定义.data有点奇怪。我总是可以声明一个变量,然后从我的代码(部分).bss中移动该变量中的值,对吧?那么,当我知道在本节中声明的变量会增加可执行文件的大小时,.text为什么要在该节中声明变量呢?.data
我也可以在 C 编程的上下文中问这个问题:如果声明它未初始化然后在代码开头为其赋值更有效,为什么我应该在声明变量时初始化它?
我认为我的内存管理方法很幼稚而且不正确,但我不明白为什么。
Pet*_*des 10
.bss是放置零初始化静态数据的地方,例如 C int x;(在全局范围内)。int x = 0;这与 static / global (静态存储类)1相同。
.data是放置非零初始化静态数据的位置,就像int x = 2; 如果将其放入 BSS 中,则需要一个运行时静态“构造函数”来初始化 BSS 位置。就像 C++ 编译器对static const int prog_starttime = __rdtsc();. (尽管它是 const,但初始化器不是编译时常量,因此它不能进入.rodata)
.bss使用运行时初始化程序对于大部分为零或填充相同值(memset / )的大数组来说是有意义的rep stosd,但在实践中,使用当前的编译器,写入char buf[1024000] = {1};将把几乎全零的1MB放入.data。
否则效率不是更高。一条mov dword [myvar], imm32指令有 10 个字节长,在可执行文件中花费的字节数是在.data. 此外,初始化代码必须被执行和加载,并且 4 个字节的 BSS 空间也占用 RAM。
相比之下,section .rodata(或.rdata在 Windows 上)编译器放置字符串文字、FP 常量和static const int x = 123; (实际上,x通常会在编译单元中使用它的任何地方作为立即数内联,让编译器优化掉任何静态存储。但是如果您采取它的地址并传递&x给函数,编译器需要它存在于内存中的某个地方,并且位于.rodata)
脚注 1:在函数内部,int x;如果编译器没有将其优化掉或放入寄存器中,则在为具有 x86 之类的堆栈的普通寄存器机进行编译时,该函数将位于堆栈上。
我也可以在 C 编程的背景下问这个问题
在 C 语言中,优化编译器将与函数内部的处理方式int x; x=5;几乎相同。int x=5;不涉及静态存储。查看实际的编译器输出通常很有启发性:请参阅如何从 GCC/clang 程序集输出中删除“噪音”?。
在函数之外,在全局范围内,您不能编写诸如x=5;. 您可以在 的顶部执行此操作main,然后欺骗编译器生成更糟糕的代码。
在带有 的函数内static int x = 5;,初始化发生一次。(在编译时)。如果您这样做,static int x; x=5;每次输入函数时静态存储都会重新初始化,并且您可能还没有使用,static除非您有其他原因需要静态存储类。(例如,返回一个指向x该函数返回后仍然有效的指针。)
| 归档时间: |
|
| 查看次数: |
2332 次 |
| 最近记录: |