Hei*_*ken 3 c memory stack endianness
我听说在x86处理器中,字节以'little-endian'字节顺序存储在内存中.意味着首先存储最低有效字节.
我无法理解这个想法及其与字节如何存储在RAM中的关系.
例如,
#include <stdio.h>
char string[6];
scanf("%5s",string);
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,如果我输入单词"Hello",则首先存储"o".(?)
根据我的理解,当你声明一个变量时,在C(和编程通用?)中,变量存储在RAM的"堆栈"部分.所以单词"Hello"会像这样存储在堆栈中:
o <Lower memory addresses>
l
l
e
H <Higher memory addresses>
Run Code Online (Sandbox Code Playgroud)
堆栈从较高的内存地址向较低的内存地址增长,处理器开始从堆栈顶部的第一个字节开始读取字节(较低的内存地址).
现在,如果我打印字符串的值,我应该看到"olleH".但显然它会打印"Hello". 这是因为little-endian字节顺序?
为简单起见,让我们讨论一台机器,其中内存中的每个字节都有一个地址.(有些机器的内存只被组织成具有多个字节的字,而不是单个字节.)在这台机器中,内存就像一个大数组,所以我们可以编写memory[37]来讨论地址37处的字节.
为了存储字符,我们只是按顺序将它们放在连续的存储位置.例如,为了存储从地址100开始的字符"Hello",我们将H设置为memory[100],at ,e at memory[101],l at memory[102],l at memory[103]和o at memory[104].在某些语言中,我们还将零值设置memory[105]为标记字符串的结尾.
这里没有端点问题.字符是有序的.
考虑一个像5678这样的整数.这个整数不适合一个8位字节.在二进制中,它是1011000101110.这需要至少两个字节来存储,一个字节包含1011,一个字节包含000101110.
当我们将它存储在从位置100开始的存储器中时,我们首先放入哪个字节?这是endian问题.有些机器将高值字节(1011)memory[100]和低值字节(000101110)放入memory[101].其他机器以其他顺序执行.高值字节是数字的"大端",低值字节是"小端",导致术语"字节序".(该术语实际上来自Jonathan Swift的Gulliver's Travels.)
(此示例仅使用两个字节.整数也可以使用四个字节或更多.)
只要有一个由较小的对象构成的对象,就会出现endian问题.这就是为什么单个字符不是问题 - 每个字符都进入一个字节.(虽然,没有物理原因你不能在内存中以相反的顺序存储字符串.我们不这样做.)当一个对象有两个或更多字节时,这是一个问题.您只需选择将字节放入内存的顺序.
堆栈的常见实现从高地址开始,并在向堆栈添加内容时向下"增长".没有特别的理由这样做; 我们也可以让堆栈以其他方式工作.这就是事物在历史上的发展方式.
堆栈增长主要发生在块中.调用函数时,它会向堆栈添加一些空间,以便为其本地数据腾出空间.因此它会将堆栈指针减少一些,然后使用该空间.
但是,在该空间内,单个对象通常存储.它们不需要反转,因为堆栈会减少.如果堆栈指针从2400变为2200,我们现在想要将对象放在2300,我们只需将其字节写入内存,从2300开始.
因此,字节顺序不是受堆栈顺序影响的问题.
| 归档时间: |
|
| 查看次数: |
1055 次 |
| 最近记录: |