【问题标题】:Why different type of symbol occupies the same length?为什么不同类型的符号占用相同的长度?
【发布时间】:2018-04-26 13:55:05
【问题描述】:

我在 x64 机器上使用 cygwin GCC 编译了以下代码:

gcc main.c -o main

(main.c)

long long mango = 13; // I also tried `char`, `short`, `int`
long melon = 2001;

void main()
{

}

然后我用nm转储符号值:

./main:0000000100402010 D mango
./main:0000000100402018 D melon

据我了解,符号的值仅表示其地址。所以mango 的地址是100402010。而melon 的地址为100402018。所以mango应该占8个字节。

我为mango尝试了其他类型,例如charintshort。它总是占用 8 个字节。

为什么大小不变?

添加 1

感谢评论。

我刚刚尝试了以下代码:

typedef struct{
    char a1;
    char a2;
    char a3;
    char a4;
    char a5;
} MyStruct;

MyStruct MyObj1={1,2,3,4,5};

MyStruct MyObj2={1,2,3,4,5};

long long mango = 13;
long melon = 2001;

void main()
{

}

这一次,nm 向我展示了这个:

./main:0000000100402020 D mango
./main:0000000100402028 D melon
./main:0000000100402010 D MyObj1
./main:0000000100402015 D MyObj2

MyObj1MyObj2 分隔 5 个字节。所以实际上由编译器决定填充。

【问题讨论】:

  • 地址没有告诉你任何关于尺寸的信息。
  • 主要做:printf("%zu %zu", sizeof(mango), sizeof(melon));
  • @smwikipedia 这可能是地址。我们所说的是地址并没有告诉你大小。 melon 可能必须位于 8 字节边界上,因此在变量之间添加了填充。但是编译器可以在这里为所欲为。
  • 请记住,编译器会在不同的边界上对齐事物并根据需要添加填充。所以在char 的情况下可能有 1 个字节大小,7 个字节填充。使用sizeof 确定大小。
  • "所以mango的地址是100402010。而melon的地址是100402018。所以mango应该占用8个字节。" --不,这意味着mango 使用不超过 8 个字节。出于性能原因(由硬件强加),这些值以处理器字的长度对齐存储在内存中。对于 64 位处理器,任何值的内存地址都是 8 字节的倍数(即 64 位)。可以告诉编译器使用不同的对齐方式,但您应该有充分的理由这样做。

标签: c object-files nm


【解决方案1】:

来自GNU nm binary utilities: nm page

符号值,在选项选择的基数中(见下文),或 默认为十六进制。符号类型。至少以下类型 被使用;其他的也取决于目标文件格式。如果 小写,符号通常是本地的;如果是大写,符号是 全局(外部)。然而,有一些小写符号是 显示为特殊的全局符号(u、v 和 w)。根据pragma 设置和默认对齐边界,连续符号地址之间的距离可能是该符号type 的字节数的精确值,也可能包括padding,其中增加符号的明显sizeof

A

    The symbol’s value is absolute, and will not be changed by further linking.
B
...

IMO 在nm 用语中使用单词 value 是不幸的,因为在这种情况下 value 用于描述符号的地址。符号(值)的地址不会改变。但在正常的 C 语言中,符号的 确实会发生变化,例如:

int i = 0; // the address for symbol i will remain constant
i = 10;    // but the value of the symbol i can change. 

关于地址的大小,64 位构建的任何符号的地址将始终具有 8 个字节的大小,而 32 位构建的任何符号的地址将具有 4 个字节的大小。这些大小不会改变,并且不会因将 value 分配给分配给它们的符号而受到影响。

关于内存空间中各种符号之间发生的距离,该距离受符号的type、沿实现边界的aligned影响,以及,当你已经注意到,编译器:“因此确实由编译器决定填充。” 根据pragma 设置和默认对齐边界,padding 可能会导致连续符号的地址比仅由定义特定符号的 typetypes 的组合 sizeof 值引起的距离更大。 (charstruct 类型符号非常常见)。

【讨论】:

  • 谢谢。我同意你的观点,nm 用语中的“价值”一词是不幸的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
  • 2015-11-27
  • 2012-12-23
  • 1970-01-01
  • 2019-02-23
  • 2019-12-07
  • 2014-03-30
相关资源
最近更新 更多