微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

小端字节顺序(在C中)

我听说在x86处理器中,字节以’little-endian’字节顺序存储在内存中.意味着首先存储最低有效字节.

我无法理解这个想法及其与字节如何存储在RAM中的关系.

例如,

#include <stdio.h>

char string[6];
scanf("%5s",string);

在上面的代码中,如果我输入单词“Hello”,则首先存储“o”.(?)

根据我的理解,当你声明一个变量时,在C(和编程通用?)中,变量存储在RAM的“堆栈”部分.所以单词“Hello”会像这样存储在堆栈中:

o    <Lower memory addresses>
l
l
e
H    <Higher memory addresses>

堆栈从较高的内存地址向较低的内存地址增长,处理器开始从堆栈顶部的第一个字节开始读取字节(较低的内存地址).

现在,如果我打印字符串的值,我应该看到“olleH”.但显然它会打印“Hello”.
这是因为little-endian字节顺序?

解决方法

为简单起见,让我们讨论一台机器,其中内存中的每个字节都有一个地址. (有些机器的内存只被组织成具有多个字节的字,而不是单个字节.)在这台机器中,内存就像一个大数组,所以我们可以写内存[37]来讨论地址37处的字节.

如何存储字符

为了存储字符,我们只是按顺序将它们放在连续的存储位置.例如,为了存储从地址100开始的字符“Hello”,我们将H放在内存[100],e放在内存[101],l放在内存[102],l放在内存[103],o放在内存[ 104].在某些语言中,我们还在内存[105]处设置零值以标记字符串的结尾.

这里没有端点问题.字符是有序的.

如何存储整数

考虑一个像5678这样的整数.这个整数不适合一个8位字节.在二进制中,它是1011000101110.这需要至少两个字节来存储,一个字节包含1011,一个字节包含000101110.

当我们将它存储在从位置100开始的存储器中时,我们首先放入哪个字节?这是endian问题.一些机器将高值字节(1011)放在存储器[100]中,将低值字节(000101110)放入存储器[101].其他机器以其他顺序执行.高值字节是数字的“大端”,低值字节是“小端”,导致术语“字节序”.(The term actually comes from Jonathan Swift’s Gulliver’s Travels.)

(此示例仅使用两个字节.整数也可以使用四个字节或更多.)

只要有一个由较小的对象构成的对象,就会出现endian问题.这就是为什么单个字符不是问题 – 每个字符都进入一个字节. (虽然,没有物理原因你不能在内存中以相反的顺序存储字符串.我们不这样做.)当一个对象有两个或更多字节时,这是一个问题.您只需选择将字节放入内存的顺序.

如何组织堆栈

堆栈的常见实现从高地址开始,并在向堆栈添加内容时向下“增长”.没有特别的理由这样做;我们也可以让堆栈以其他方式工作.这就是事物在历史上的发展方式.

堆栈增长主要发生在块中.调用函数时,它会向堆栈添加一些空间,以便为其本地数据腾出空间.因此它会将堆栈指针减少一些,然后使用该空间.

但是,在该空间内,单个对象通常存储.它们不需要反转,因为堆栈会减少.如果堆栈指针从2400变为2200,我们现在想要将对象放在2300,我们只需将其字节写入内存,从2300开始.

因此,字节顺序不是受堆栈顺序影响的问题.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐