我很好奇小端 我知道计算机几乎都有小端方法。
所以,我通过一个程序进行了调查,来源如下。
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?
答案 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
--------