使用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
答案 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唯一的方法是自己在堆栈或堆(或全局)上分配一块内存,然后保证连续的内存。