0

对于我正在从事的项目,我使用幻数。该宏用于定义一个

#define BOOTSIGNATURE 0xAA55

但是,当我对生成的文件进行 HEXDUMP 处理时,应该说 AA55 它说 55 AA。

GCC 是在混淆字节顺序,还是我?该项目适用于 x86 处理器。AA 55 需要按特定顺序排列。我可以只交换字节,但我很好奇 GCC 为什么要这样做。

4

4 回答 4

2

0xAA55是一个int,所以你受制于你的机器的字节序。我会将其存储为 char 数组:

const unsigned char BOOTSIGNATURE[] = {0xAA, 0x55};
于 2012-11-09T20:48:17.223 回答
2

预处理器宏不会出现在编译的目标文件中——编译器根本看不到它们。如果您只是拥有它#define并且从未在任何地方使用过它,那么就不会留下任何痕迹。

如果您在某处的代码中使用它,它可能会在指令中显示为常量(例如,将常量加载到寄存器或内存中)。如果您使用它来初始化静态数据,它将在数据段中显示为常量:

// Global variable definition
#define BOOTSIGNATURE 0xAA55
uint16_t my_global = BOOTSIGNATURE;

如果你编译上面的代码并查看数据段,它看起来像这样:

$ gcc -c test.c
$ objdump -s test.o
[...]
Contents of section .data:
 0000 55aa0000                             U...

如您所见,这两个字节以 little-endian 顺序存储在内存中55 AA(前导0000是十六进制的段偏移量)。

如果要控制数据的字节顺序,请将其存储为显式字节数组:

uint8_t my_global[] = {0xAA, 0x55};

这将始终按指定的顺序存储字节。

于 2012-11-09T20:52:59.490 回答
0

如果你想编写可移植的代码,你会使用函数来强制一个给定的字节顺序。例如,这些函数允许您将本机主机字节顺序中的 16 位值转换为大端或小端,具体取决于您在文件中需要的顺序。

#define BOOTSIGNATURE 0xAA55

struct bootheader {
   uint16_t    signature_be;
} header;

header.signature_be = htobe16( BOOTSIGNATURE);

我喜欢在具有非主机字节顺序的变量和结构元素上使用_leor后缀。_be

由于您需要大端,您可以使用htons()from arpa/inet.h,但我不是该方法的忠实粉丝。我不认为名称像 一样清晰htobe16,并且您没有用于转换为小端字节顺序的功能。

于 2012-11-15T01:46:51.477 回答
-2

最简单的解决方案:使用十六进制值的整数形式,因此相应的二进制将产生相同的幻数!在这种情况下,这将是 43605

于 2012-11-09T21:01:22.653 回答