MARS MIPS 模拟器 ASCII 字符串未正确存储在小端内存中?

MARS MIPS Simulator ASCII string not storing in memory in little-endian properly?

我听说 MARS MIPS 模拟器是小端的,所以我希望如果我在内存中使用 .asciiz "HELLO" 保留字符串“HELLO”,我会找到字符 O位于给定字符串的最低内存地址中,H 位于给定字符串的最高内存地址中。

但是当我组装代码时,MARS 的调试器显示内存如下:

H存放在0x10010000地址(数据段基地址)而O存放在0x10010004——显然存放在更高的内存地址。这不是大端吗?

但是,我注意到当我使用 .word 0xABCD 保留像 0x0000ABCD 这样的字长数据时,D 将被放置在最低内存中,就像小端一样系统必须做的。为什么他们以不同的方式存储数据?

字符串是一个字节序列,而不是一个巨大的整数。无论机器字节序如何,字符串的第一个字节始终是最低地址。

机器字节序只决定了你在寄存器中得到的值,如果你这样做了lw $t0, my_string

但是如果你用 lbu $a0, ($t1) / addiu $t1, $t1, 1 遍历字符串的字节,你肯定想按照你在源代码中写入的顺序获取 ASCII 字节:H,E, L, L, O, 0.

如果要向后存储字符串,请使用 .asciiz "OLLEH"


字节流没有结尾,只有 CPU 可以通过单次访问加载的内容。 endianness 的整个概念来自能够访问单词的各个字节,例如sw 然后 lbu.

如果你可以使用lw/sw那么硬件字节顺序就不是问题了,这将取决于软件如何转移/ OR 或 AND 访问 32 位整数中的位,如果它想打包 8 位 ASCII 字符。或者,如果您 甚至可以使用 lbu / sb,则由软件决定存储较长整数的单独字节的顺序。

对于字符串,每个人都会做出明智的选择,以打印顺序存储它们,第一个字节在最低地址。这恰好与您希望它们在文本文件中或在一行内从左到右扫描的视频 RAM 中的顺序相匹配。

所以,当你实现一个高效的 strlen 时,字节顺序只对字符串很重要,它一次检查 4 个字节 0,使用 bithack 或其他东西:https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord .

虽然那个 bithack 实际上并没有告诉你 区别在哪里,所以也许一个更好的例子是如果你通过比较 4 个字节来实现 strcmp ( 1 个单词)一次。如果不匹配,您可以在这些单词中一次循环 1 个字节以找到不同的确切字符,或者您可以将两个单词异或在一起,然后找到最低设置位(小端)或最高位的位置设置位(big-endian)以找出哪个字节包含第一个位差。 (我不知道 MIPS 是否有 clz / ctz 计数前导/尾随零指令,但如果有,你可以这样使用它们。)