8位处理器需要面对字节序问题吗?

5

如果我在8位处理器 (比如8051) 的内存里有一个int32类型的整数,我该如何确定这个整数的字节序(endianess)?这是与编译器有关的吗?当通过串行线传输多字节数据时,了解它的字节序十分重要。


1
只有一种情况您不需要考虑大小端问题,那就是当您没有多字节整数的时候。只要通信渠道标准化为使用 8 位单位,您在使用 8 位时才是安全的。如果您的通信渠道使用其他任何大小,即使使用 8 位单位(例如,半字节,哪个半字节是高位,哪个是低位?),您也必须担心大小端问题。这与处理器类型无关。 - falstro
即使您没有多字节整数,通道设计人员也必须在电线上指定最不重要位(lsb-first)或最重要位(msb-first),并且设备建造的工作人员必须尊重这一点... - dmckee --- ex-moderator kitten
是的,这正是我的情况。当我在传输多字节数据时,我必须同时了解协议和内存布局... - Grissiom
7个回答

8

当使用一个没有本地支持更宽整数的8位微控制器时,存储在内存中的整数的字节序确实取决于编译器的编写者。

SDCC编译器广泛应用于8051,以小端格式存储整数(该编译器的用户指南声称,在该体系结构上更有效率,因为存在增加数据指针但不存在减少数据指针的指令)。


4
Keil C51编译器将整数存储为大端格式。 - mocj
2
C51编译器假定使用sbit声明访问的对象以小端字节顺序存储。这适用于sfr16类型。然而,标准C类型如intlong则以大端字节顺序存储。 - jschmier

5

谢谢!我会结合caf、SF和你的回答来想出一个主意。感谢你的链接 ;) - Grissiom

3
字节序是与CPU架构有关的。由于编译器需要针对特定的CPU进行编译,因此编译器也会了解字节序。因此,如果您需要通过串行连接、网络等发送数据,则可能希望使用内置函数将数据放入网络字节顺序中,特别是如果您的代码需要支持多个架构。
更多信息请参见:http://www.gnu.org/s/libc/manual/html_node/Byte-Order.html

除非您正在使用Motorola 88000,否则内存中数据的字节序是由指令编码定义的,因此大端和小端可以自由交换。 - Skizz
是的,但正如道格拉斯所指出的那样,一旦你将数据发送到任何地方,你就必须处理字节序。 - Hugh Brackett

3

编译器并不是唯一的决定因素 - '51芯片有一些本地的16位寄存器(DPTR,标准中的PC,变体中的ADC_IN,DAC_OUT等)具有特定的字节序,编译器必须遵守 - 但除此之外,编译器可以自由选择任何喜欢的字节序或者你在项目配置中选择的字节序...


2
一个整数本身没有字节序。你不能仅仅通过查看字节来确定它是大端还是小端。你需要知道:例如,如果你的8位处理器是小端的,并且你接收到一个你知道是大端的消息(因为,例如,字段总线系统定义为大端),你必须转换超过8位的值。你需要将其硬编码或在系统上定义哪些字节需要交换。
请注意,交换字节很容易。你可能还需要交换位域中的位,因为位域中的位的顺序是与编译器相关的。同样,你基本上需要在构建时了解这一点。

1
unsigned long int x = 1;
unsigned char *px = (unsigned char *) &x;

*px == 0 ? "big endian" : "little endian"

如果将x赋值为1,则最低有效字节中将包含值1。 然后,如果我们将x强制转换为指向字节的指针,则该指针将指向x的最低内存位置。如果该内存位置为0,则为大端序;否则为小端序。

这只是一种测试方式,而不是答案。 - Grissiom

0
#include <stdio.h>

union foo {
    int as_int;
    char as_bytes[sizeof(int)];
};

int main() {
    union foo data;
    int i;
    for (i = 0;  i < sizeof(int);  ++i) {
        data.as_bytes[i] = 1 + i;
    }
    printf ("%0x\n", data.as_int);
    return 0;
}

如何解释输出结果由您决定。


或者使用memcpy,它对实现做出了稍微弱一些的假设:“int asint; char asbytes[sizeof(int)]; <设置字节>; memcpy(&i, asbytes, sizeof(int));”。 - Steve Jessop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接