我很难理解内存如何与MIPS协同工作。我意识到MIPS中有签名和无符号指令,例如add
和addu
,但我怎么知道我从内存加载或存储到内存的是有符号或无符号位?另外,为什么lw
指令已签名,但加载半字或加载字节的指令只有无符号ie lhu and lbu
?
非常感谢任何澄清!
答案 0 :(得分:4)
如何知道我从内存加载或存储到内存中的是有符号或无符号位?
在MIPS程序集中编程时,没有类型系统。因此,您有责任跟踪操作是应该签名还是未签名。对于add/addu
和sub/subu
,唯一的区别是签名版本会在溢出时导致异常。
加载半字或加载字节的指令只有无符号即lhu和lbu
这些版本的签名版本为lh
和lb
。
为什么签署了lw指令
如果将lh/lhu
的半字加载到寄存器中,则会对寄存器的下半部分执行此操作。这会在寄存器顶部留下16位,需要填充一些值。当使用无符号版本时,执行零扩展,这对于" left"不会影响价值。使用带符号的加载时,会执行符号扩展。
lw
没有高位,需要填充。因此,只需要一个版本。
答案 1 :(得分:3)
内存就是内存,一组字节或位。它本身不携带任何元数据,布局或类型信息。
如果您希望它包含此信息,请将其存储在那里,然后检索并解释它。但是,在许多情况下,这不是完成,因为它是一种矫枉过正。你想处理像XML或JSON这样的东西只是为了读或写一些字节或单词吗?你可能不会。
所以如果你不这样做,那么你有责任为你的程序适当地处理内存位置。如果要将存储器单元用于16位有符号类型,请记住这一点,并使用适合该类型的load / divide / shift / etc指令。
汇编语言在很大程度上与绝大多数其他编程语言不同,它没有提供任何方法来声明类型变量并根据类型自动选择使用它们的指令。这是有意的,以便使装配工小巧,简单和快速,并且密切反映硬件,CPU架构。 CPU几乎不了解类型,只要它不会导致CPU复位或关闭(可能由于过热),它们无法理解它们正在运行的软件。例如。任意值都可以加载到通用寄存器中,即使是浮点常数,也可能是非常好的,尽管CPU中有特殊的浮点寄存器似乎更适合这种类型/值。
使用lb / lbu / lh / lhu指令对一个字节或一个半字进行符号扩展或零扩展只有在有空间进行扩展时才有意义。 MIPS通用寄存器是32位。 lw加载32位并且无处可扩展,所以,没有lwu ......直到你得到一个带有64位寄存器的64位MIPS CPU,毫不奇怪你有lwu(加载32位,零扩展; lw确实如此)符号扩展)和ld(加载64位)。但是没有ldu。你知道为什么吗? :)