为什么整数类型需要是little-endian?

时间:2015-06-13 07:43:51

标签: c stack endianness

我很好奇小端 我知道计算机几乎都有小端方法。

所以,我通过一个程序进行了调查,来源如下。

setvbuf(stdout, NULL, _IONBF, 0);

当我通过gdb看到堆栈时,

我注意到有 0x00007a69 0x00007a69 ...... ...... ...... .... 0x62610000 0x00656463 .. ...

所以,我有两个问题。

首先,

int main(){ int flag = 31337; char c[10] = "abcde"; int flag2 = 31337; return 0; } 的价值如何在旗帜下?

我预计在堆栈顶部有flag2的值,在flag2下有char c [10]的值,在char c [10]下有flag的值。

像这样

char c[10]

其次,

我预计这个值会以little-endian的方式存储。

结果,“abcde”的值存储为“6564636261”

但是,31337的值并未通过little-endian存储。

这只是'7a69'。 我以为它应该是'697a'

为什么整数类型不符合little-endian?

4 个答案:

答案 0 :(得分:7)

您对字节序,堆栈和编译器的理解存在一些混淆。

首先,堆栈中变量的位置可能与编写的代码无关。例如,编译器可以自由地移动它们的方式,除非它是结构的一部分。通常他们会尝试尽可能高效地使用内存,因此需要这样做。例如,char,int,char,int需要16个字节(在32位机器上),而int,int,char,char只需要12个字节。

其次,char数组中没有“endianness”。他们就是这样:价值数组。如果你在那里放“abcde”,那么值必须按顺序排列。如果您将使用例如UTF16,那么字节顺序将起作用,因为那时代码字的一部分(不一定是一个字符)将需要两个字节(在普通的8位机器上)。这些将根据字节顺序存储。

十进制值31337在32位十六进制中为0x007a69。如果您要求调试器显示它,它将以无论字节顺序显示它。查看它在内存中的唯一方法是将其转储为字节。然后它将是小端的0x69 0x7a 0x00 0x00。

此外,尽管小端是非常受欢迎的,但主要是因为x86硬件很受欢迎。许多处理器使用大端(SPARC,PowerPC,MIPS等)订单,有些(如旧的ARM处理器)可以在任何一个中运行,具体取决于要求。

还有一个术语“网络字节顺序”,实际上是大端。这与小端机器最受欢迎之前的时间有关。

答案 1 :(得分:1)

整数字节顺序是任意处理器设计决策。例如,为什么你似乎对little-endian感到不舒服?是什么让big-endian成为更好的选择呢?

很可能是因为你是一个习惯于从左到右阅读数字的人;但机器几乎不在乎。

实际上有一个合理的论据,即将最低有效字节置于最低阶地址是直观的;但同样,只能从人类直觉的角度出发。

答案 2 :(得分:0)

GDB 显示 0x62610000 0x00656463,因为它将数据(...abcde...)解释为小端系统上的32位字。

它可以是两种方式,但合理的默认值是使用 native endianness。

内存中的数据只是一个字节序列。如果你告诉它将它显示为短整数的序列(数组),它会改变它显示的内容。许多调试器具有高级内存视图功能,以各种解释显示内存内容,包括字符串,整数(十六进制),整数(十进制),浮点数等等。

答案 3 :(得分:0)

你已经得到了一些很好的答案。 这里有一些代码可以帮助您理解变量在内存中的布局,使用little-endian或big-endian:

#include <stdio.h>

void show_var(char* varname, unsigned char *ptr, size_t size) {
 int i;
 printf ("%s:\n", varname);
 for (i=0; i<size; i++) {
     printf("pos %d = %2.2x\n", i, *ptr++);
 }
 printf("--------\n");
}

int main() {
 int flag = 31337;
 char c[10] = "abcde";

 show_var("flag", (unsigned char*)&flag, sizeof(flag));
 show_var("c", (unsigned char*)c, sizeof(c));
}

在我的Intel i5 Linux机器上,它产生:

flag:
pos 0 = 69
pos 1 = 7a
pos 2 = 00
pos 3 = 00
--------
c:
pos 0 = 61
pos 1 = 62
pos 2 = 63
pos 3 = 64
pos 4 = 65
pos 5 = 00
pos 6 = 00
pos 7 = 00
pos 8 = 00
pos 9 = 00
--------