我如何知道 MIPS 内存地址中的某些内容是有符号数据还是无符号数据?
How do I know if something in a MIPS memory address is signed or unsigned data?
我很难理解内存如何与 MIPS 一起工作。我知道 MIPS 中既有有符号指令也有无符号指令,例如 add
和 addu
但是我怎么知道我从内存加载或存储到内存的是有符号位还是无符号位?另外,为什么lw
指令是有符号的,而加载半字或加载字节的指令却只有无符号的ie lhu and lbu
?
任何澄清将不胜感激!
how do I know if what I am loading from or storing to memory is signed or unsigned bits?
您在使用 MIPS 汇编编程时没有类型系统。因此,您有责任跟踪操作是否应该签名或未签名。在 add/addu
和 sub/subu
的情况下,唯一的区别是签名版本会导致溢出异常。
instructions for loading a half word or loading a byte only come in unsigned ie lhu and lbu
有签名版本,lh
和 lb
。
why is the lw instruction signed
如果将带有 lh/lhu
的半字加载到寄存器中,则会加载到寄存器的下半部分。这会在寄存器顶部留下 16 位,需要用一些值填充。使用无符号版本时,会执行零扩展,这很好,因为 "left" 的零不会影响值。使用带符号的加载时,改为执行符号扩展。
对于lw
,没有需要填充的高位。所以,只需要一个版本。
内存就是内存,字节或位的集合。它本身不携带任何元数据、布局或类型信息。
如果你想让它包含这些信息,你可以把它存储在那里,然后检索和解释它。然而,在许多情况下,这并没有完成,因为这是一种矫枉过正的做法。您想处理 XML 或 JSON 之类的东西只是为了读取或写入几个字节或单词吗?你可能不会。
因此,如果您不这样做,您有责任为您的程序适当地处理内存位置。如果您想将存储单元用于 16 位有符号类型,请牢记这一点并使用适合该类型的 load/divide/shift/etc 指令。
在大多数情况下,与绝大多数其他编程语言不同,汇编语言不提供任何方法来声明类型化变量并根据它们的类型自动选择指令来使用它们。这是有意为之的,目的是使汇编器保持小巧、简单和快速,并密切反映硬件 CPU 体系结构。 CPUs 对类型几乎一无所知,也无法理解它们是 运行 的软件,只要它不会导致 CPUs 重置或关闭(可能是由于过热)。例如。可以将任意值加载到通用寄存器中,甚至是浮点常量,尽管 CPU 中有特殊的浮点寄存器似乎更适合这种 types/values.
使用那些 lb/lbu/lh/lhu 指令对字节或半字进行符号扩展或零扩展只有在有 space 扩展时才有意义。 MIPS 通用寄存器是 32 位的。 lw 加载 32 位并且没有地方可以扩展,所以,没有 lwu ......直到你得到一个带有 64 位寄存器的 64 位 MIPS CPU,毫不奇怪你确实有 lwu(加载 32 位零扩展;lw 做符号扩展)和 ld(加载 64 位)。但是没有ldu。你知道为什么吗? :)
我很难理解内存如何与 MIPS 一起工作。我知道 MIPS 中既有有符号指令也有无符号指令,例如 add
和 addu
但是我怎么知道我从内存加载或存储到内存的是有符号位还是无符号位?另外,为什么lw
指令是有符号的,而加载半字或加载字节的指令却只有无符号的ie lhu and lbu
?
任何澄清将不胜感激!
how do I know if what I am loading from or storing to memory is signed or unsigned bits?
您在使用 MIPS 汇编编程时没有类型系统。因此,您有责任跟踪操作是否应该签名或未签名。在 add/addu
和 sub/subu
的情况下,唯一的区别是签名版本会导致溢出异常。
instructions for loading a half word or loading a byte only come in unsigned ie lhu and lbu
有签名版本,lh
和 lb
。
why is the lw instruction signed
如果将带有 lh/lhu
的半字加载到寄存器中,则会加载到寄存器的下半部分。这会在寄存器顶部留下 16 位,需要用一些值填充。使用无符号版本时,会执行零扩展,这很好,因为 "left" 的零不会影响值。使用带符号的加载时,改为执行符号扩展。
对于lw
,没有需要填充的高位。所以,只需要一个版本。
内存就是内存,字节或位的集合。它本身不携带任何元数据、布局或类型信息。
如果你想让它包含这些信息,你可以把它存储在那里,然后检索和解释它。然而,在许多情况下,这并没有完成,因为这是一种矫枉过正的做法。您想处理 XML 或 JSON 之类的东西只是为了读取或写入几个字节或单词吗?你可能不会。
因此,如果您不这样做,您有责任为您的程序适当地处理内存位置。如果您想将存储单元用于 16 位有符号类型,请牢记这一点并使用适合该类型的 load/divide/shift/etc 指令。
在大多数情况下,与绝大多数其他编程语言不同,汇编语言不提供任何方法来声明类型化变量并根据它们的类型自动选择指令来使用它们。这是有意为之的,目的是使汇编器保持小巧、简单和快速,并密切反映硬件 CPU 体系结构。 CPUs 对类型几乎一无所知,也无法理解它们是 运行 的软件,只要它不会导致 CPUs 重置或关闭(可能是由于过热)。例如。可以将任意值加载到通用寄存器中,甚至是浮点常量,尽管 CPU 中有特殊的浮点寄存器似乎更适合这种 types/values.
使用那些 lb/lbu/lh/lhu 指令对字节或半字进行符号扩展或零扩展只有在有 space 扩展时才有意义。 MIPS 通用寄存器是 32 位的。 lw 加载 32 位并且没有地方可以扩展,所以,没有 lwu ......直到你得到一个带有 64 位寄存器的 64 位 MIPS CPU,毫不奇怪你确实有 lwu(加载 32 位零扩展;lw 做符号扩展)和 ld(加载 64 位)。但是没有ldu。你知道为什么吗? :)