MIPS - 存储为字节的字符是否与未存储为字节的字符相同?

问题描述 投票:0回答:1

我是MIPS的新手,我只是想知道,我通过以下方式存储空格字符:

li $t0, ' '
lb $t1, ' '

la $t2, myArray  # load array
sb $t0, 0($t2)   # myArray[0] = ' '

在这种情况下是$ t0 == $ t1? sb指令有效吗?我有点困惑的是我是否可以互换地使用字节和整数(单词)。

assembly mips mips32
1个回答
0
投票

byteword不能自由互换,因为byte只有8位信息,而word是32位信息(在MIPS平台上)。因此,byte可以设置为256个不同的可能值(8个0/1位值的28个组合),并且word可以设置为2564个不同的可能值(32位模式)。

您需要四个字节来存储相同的可能信息量,例如您可以适合单个字(8位* 4 = 32位)。

但是,根据您正在处理的值,如果您可以保证它们的范围,您可以预测字节/半字/字之间的代码转换值如何表现,某些值是否会在没有任何损坏的情况下保持这种转换,或者它需要额外的验证/处理。例如,如果您的输入值是ASCII字符(来自字符串),那么这些只是7位(当解释为有符号整数时,仅在ASCII中定义值0到+127)。

因此,例如li $t0, ' '将汇编为li $t0, 32(因为“空格”字符在计算机中编码为值32)并且因为li指令采用操作符号整数立即。

实际上“li”不是真正的MIPS指令,而是一个方便的伪指令,汇编器会将其转换为一个/两个本机指令来编码/组合所需的立即值。尝试使用值为+1,-1,+ 65000,-65000的li $t0, ...示例,并在调试器中观察它如何组合成不同的本机指令,实现所需的“立即加载”效果,例如-65000值至少需要两个本机要编写的说明。

所以你在技术上将32位(字)值加载到$ t0(即使' '只是值32,它很容易适合字节)。

但是如你所知,你确实将ASCII“空间”加载到t0中,无论t0是32位“宽”,你知道它只足以将“byte”存储到内存中,如果你是在缓冲区中创建新的字符串,你想把空格字符放入其中。那么sb $t0, 0($t2)是正确的。你在t0中有一个更大的值,高24位被忽略,只有低8位的值用sb指令写入内存(有效地“截断”内存中的那个值,它不可能从内存中读回完整的值,只有截断的部分)。


在MIPS汇编中,其他方向的转换也经常发生,因为例如lb将只从存储器中读取8位,但它会将它们符号扩展为完整寄存器(32位)。如果你不注意你的价值观,你可能很容易陷入困境,例如:

.data
test_value: .byte 234
.text
    li      $t0, 234
    lb      $t1, test_value
    tne     $t0, $t1     # throw exception if t0 is not equal to t1
    # terminate normally when values are equal
    li      $v0, 10
    syscall

这可能看起来是第一次读取,因为它的值234与234相比,因此程序通常会终止,但如果你试图运行它,它将在tne指令处以异常结束。因为当你将该位模式解释为“无符号8位整数”时,lb对值进行符号扩展并且234适合8位,如果将相同的位模式解释为“有符号8位整数”,则它变为值-22-22不等于234

你会将lb指令更改为加载“无符号字节”的lbu,代码将正常工作并正常退出,因为tne将比较234和234值相等。

因此,在汇编编程时,您应该清楚地了解您处理的数据类型,并根据需要正确地扩展/截断这些值。

(顺便说一下,MARS汇编程序会警告你“234”不适合“有符号字节”和可能的截断 - 但是高达255的值实际上适合8位,只需要以“无符号”方式解释。高于255的值将得到真正被截断,就像有些位完全缺失一样,例如.byte 1025将只在内存中存储值1

© www.soinside.com 2019 - 2024. All rights reserved.