이정민*_*이정민 0 c stack endianness
我很好奇小端,我知道计算机几乎都有小端方法.
所以,我通过一个程序进行了调查,来源如下.
int main(){
int flag = 31337;
char c[10] = "abcde";
int flag2 = 31337;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我通过gdb看到堆栈时,
我注意到有0x00007a69 0x00007a69 ...... ...... ...... .... ... 0x62610000 0x00656463 ......
所以,我有两个问题.
一方面,
如何能够char c[10]在旗帜下的价值?
我预计在堆栈顶部有flag2的值,在flag2下有char c [10]的值,在char c [10]下有flag的值.
像这样
7a69
"abcde"
7a69
Run Code Online (Sandbox Code Playgroud)
第二,
我预计价值会以小端的方式存储.
结果,"abcde"的值存储为"6564636261"
但是,31337的值不是通过little-endian存储的.
那只是'7a69'.我以为它应该是'697a'
为什么整数类型不符合little-endian?
您对字节序,堆栈和编译器的理解存在一些混淆.
首先,堆栈中变量的位置可能与编写的代码无关.例如,编译器可以自由地移动它们的方式,除非它是结构的一部分.通常他们会尝试尽可能高效地使用内存,因此需要这样做.例如,char,int,char,int需要16个字节(在32位机器上),而int,int,char,char只需要12个字节.
其次,char数组中没有"endianness".他们就是这样:价值数组.如果你在那里放"abcde",那么值必须按顺序排列.如果您将使用例如UTF16,那么字节顺序将起作用,因为那时代码字的一部分(不一定是一个字符)将需要两个字节(在普通的8位机器上).这些将根据字节顺序存储.
32位十六进制的十进制值31337是0x007a69.如果您要求调试器显示它,它将以无论字节顺序显示它.查看它在内存中的唯一方法是将其转储为字节.然后它将是小端的0x69 0x7a 0x00 0x00.
此外,尽管小端是非常受欢迎的,但主要是因为x86硬件很受欢迎.许多处理器使用大端(SPARC,PowerPC,MIPS等)订单,有些(如旧的ARM处理器)可以在任何一个中运行,具体取决于要求.
还有一个术语"网络字节顺序",实际上是大端.这与小端机器最受欢迎之前的时代有关.