是否有关于__DATA标签的相对地址的保证?

时间:2016-05-14 03:55:34

标签: c unix x86-64

使用Clang / LLVM编译时(Apple LLVM版本6.1.0(clang-602.0.49) 目标:x86_64-apple-darwin14.3.0)下面的C代码打印出来22.我实际上并不关心C标准,但我想知道是否有办法制作一个标签,使其偏离-8字节还有我选择的另一个四字。我希望它可以在Mac OS X和Linux上运行。

#include<stdio.h>

long long x = 22;
long long y = 33;

int main(void) {
  long long diff = *(&y - 1);
  printf("%lld\n",diff);
}

使用DATA部分的相关部分。

   .section  __DATA,__data
   .globl  _x                      ## @x
   .align  3
 _x:
   .quad 22                      ## 0x16

   .globl  _y                      ## @y
   .align  3
 _y:
   .quad 33                      ## 0x21

2 个答案:

答案 0 :(得分:2)

编译器可以按任意顺序自由放置静态/全局对象。功能相同。编译器可能会尝试将&#34; hot&#34;或者&#34;冷&#34;数据或功能在一起,以减少缓存占用空间。

如果要从一个基指针引用多个内容,请将它们放在结构或数组中。正如@kcraigie在评论中建议的那样,数组和结构之间的union是可能的。 (但可能并不有用)。

保证内存中的数组布局。 struct布局也有一些保证,但可能不会禁止编译器将填充放在你不期望的地方。但是,struct布局对于给定的ABI是固定的,因此您可以依赖于在同一平台上针对相同ABI的所有编译器的相同结构布局。

如果您真的关心内存中的布局,可以使用enum或使用宏来为不同的数组元素指定符号名称,以将GLOBAL_X定义为global_array[0]或其他内容。否则只需使用struct,如果您将事物分组在一起的目的是能够将它们复制为块,那么这将很有效。

与@ kcraigie的回答相反,没有必要动态分配内存块。静态数组或结构可以很好地完成工作。显然,如果您不需要,静态存储是一种浪费:尽可能使用自动(堆栈)存储。

re:评论中的问题:

  

如果汇编程序放在数据部分中,那么汇编程序会将它们放在每个旁边吗?

是。汇编程序只是将字节汇编到一个目标文件中,没有可以在一个中移动的空间。 .align指令可以产生间隙,但是我们知道x和y之间的.align将扩展为0字节(因为x之前的.align,已经将其置于8字节边界)

不同的部分(.text / .rodata.data对比任何自定义部分)只会在链接时放入最终订单。

答案 1 :(得分:0)

任何理智的C编译器都应该将它们放在连续的内存中,但不能保证。 AFAIK唯一的方法是自己在堆栈或堆(或全局)上分配一块内存,然后保证连续的内存。