关于 MIPS lb 和 sb 以及字节序
About MIPS lb and sb and endianness
我刚刚在 .
中阅读了@Cheshar 的评论
这是我对他的第一点的推理:$t0
中的值应该是 0xFFFFFF90
(即它是符号扩展的)但这不会改变结果mem(4)
(我认为这意味着阅读从 0x04
开始的单词)仍然是 FFFF90FF
。我说得对吗?
但我不确定他的第二点:
["] lb
and sb
doesn't care for endianness. [."]
我在想为什么
从大端到小端的变化是
byte: 0 1 2 3 ----\ 3 2 1 0
00 90 12 A0 ----/ 00 90 12 A0
所以看起来单个字节仍然像大端一样读取?
lb/sb
不 关心字节顺序。 没有 单个字节的字节序。
仅当您存储 big/little 字节序 [(例如)4 字节] 数字然后尝试逐字节访问它时才有意义。
byte 偏移不会改变,所以更好的图表可能是:
byte: 0 1 2 3 ----\ 0 1 2 3
00 90 12 A0 ----/ A0 12 90 00
如果 $t1
指向您存储的整数,当您这样做时:
lb $t0,1($t1)
对于小端,你得到 90
,对于大端,你得到 12
。
更新:
I upvote your answer since it's clean. But didn't you think that is counter intuitive before? Since in little endian the 32-bit integer has no meaning when read 32-bit all together from either left to right or right to left...?
一旦数据进入寄存器(通过 lw
),我们将其可视化并作为大端操作(即左移 1 就是乘以 2)。
小数123
是"big endian"(一百+二十+三)。
小端只是我们从内存中读取或存储时的字节顺序。硬件将根据需要随机排列字节。
little endian 的优点是它对大的多精度数字(例如 libgmp
)更有效。
并且,当 Intel 首次推出 8 位 8080 处理器(只有单字节内存总线)时,小端法让事情变得更快。例如,当执行 add
时,在获取偏移量 0 处的 LSB 后,它可以在获取偏移量 1 处的 MSB 的同时并行执行两个 LSB 字节的相加。
To give an example: 8-bit (unsigned) integer b00100001 is 33(decimal), but with little endian it is stored as b00010010, which is 18(decimal) when read from left to right, and b01001000, which is 64+8=72(decimal) when read from right to left, bit by bit.
虽然 [理论] 计算机体系结构有可能像您描述的那样运行,但 [据我所知] 的现代计算机体系结构都没有。这部分是因为这样做需要更复杂的电路。
然而,我曾经写过一个多精度数学包,确实在字节中使用小端字节和小端位。但是,慢。这有时对大位向量很有用(例如 500,000 位宽)
Or my idea is completely wrong since computer can only see byte as an abstraction of underlying bits.
一个字节中 位 的字节顺序是相同的(大端),无论该字节是在寄存器中还是在内存单元中。
不同的字节顺序仅适用于多字节整数(例如,在 C 中,int
或 short
)。
我刚刚在
这是我对他的第一点的推理:
$t0
中的值应该是0xFFFFFF90
(即它是符号扩展的)但这不会改变结果mem(4)
(我认为这意味着阅读从0x04
开始的单词)仍然是FFFF90FF
。我说得对吗?但我不确定他的第二点:
["]
lb
andsb
doesn't care for endianness. [."]我在想为什么 从大端到小端的变化是
byte: 0 1 2 3 ----\ 3 2 1 0 00 90 12 A0 ----/ 00 90 12 A0
所以看起来单个字节仍然像大端一样读取?
lb/sb
不 关心字节顺序。 没有 单个字节的字节序。
仅当您存储 big/little 字节序 [(例如)4 字节] 数字然后尝试逐字节访问它时才有意义。
byte 偏移不会改变,所以更好的图表可能是:
byte: 0 1 2 3 ----\ 0 1 2 3
00 90 12 A0 ----/ A0 12 90 00
如果 $t1
指向您存储的整数,当您这样做时:
lb $t0,1($t1)
对于小端,你得到 90
,对于大端,你得到 12
。
更新:
I upvote your answer since it's clean. But didn't you think that is counter intuitive before? Since in little endian the 32-bit integer has no meaning when read 32-bit all together from either left to right or right to left...?
一旦数据进入寄存器(通过 lw
),我们将其可视化并作为大端操作(即左移 1 就是乘以 2)。
小数123
是"big endian"(一百+二十+三)。
小端只是我们从内存中读取或存储时的字节顺序。硬件将根据需要随机排列字节。
little endian 的优点是它对大的多精度数字(例如 libgmp
)更有效。
并且,当 Intel 首次推出 8 位 8080 处理器(只有单字节内存总线)时,小端法让事情变得更快。例如,当执行 add
时,在获取偏移量 0 处的 LSB 后,它可以在获取偏移量 1 处的 MSB 的同时并行执行两个 LSB 字节的相加。
To give an example: 8-bit (unsigned) integer b00100001 is 33(decimal), but with little endian it is stored as b00010010, which is 18(decimal) when read from left to right, and b01001000, which is 64+8=72(decimal) when read from right to left, bit by bit.
虽然 [理论] 计算机体系结构有可能像您描述的那样运行,但 [据我所知] 的现代计算机体系结构都没有。这部分是因为这样做需要更复杂的电路。
然而,我曾经写过一个多精度数学包,确实在字节中使用小端字节和小端位。但是,慢。这有时对大位向量很有用(例如 500,000 位宽)
Or my idea is completely wrong since computer can only see byte as an abstraction of underlying bits.
一个字节中 位 的字节顺序是相同的(大端),无论该字节是在寄存器中还是在内存单元中。
不同的字节顺序仅适用于多字节整数(例如,在 C 中,int
或 short
)。