【问题标题】:Comparing word against immediate value?将单词与即时价值进行比较?
【发布时间】:2021-09-16 18:17:41
【问题描述】:

我正在努力掌握如何在 MIPS 中操作/比较存储在寄存器中的数据(字/半字/中间值)。如果它们各自代表不同的字节数有关系吗?例如,通过li加载5等立即数,然后加载5等单词,最后用bne进行比较是否有效?

【问题讨论】:

  • 前导零不会改变比较中的减法使用整个寄存器的值,因此您不能对它的一小部分进行操作 0x00000005 = 5

标签: assembly mips immediate-operand


【解决方案1】:

它们是否代表不同的字节数有关系吗?

简短回答:不,没关系,因为 5 就是 5。

更长的答案:MIPS 寄存器都是 32 位宽,从某种意义上说,没有办法一次操作少于 32 位 — 除了字节和半字加载/存储指令(尽管即使是这些加载也会填充一个完整的 32 位寄存器)。

例如,如果您的数据在内存中并且是 8 位宽(例如字符或字节),并且是有符号(无符号)数据类型,那么您可以使用 lb(lbu) 将其加载到32 位寄存器,同时符号(零)将 8 位值扩展到 32 位。在数值上,符号(零)扩展保持值相同,因此您现在可以使用寄存器中的 32 位值。

(当然,您必须提前知道 8 位数据是否为数字,并且应该是符号与零扩展。我们在高级语言中通过逻辑变量的声明(和永久)数据类型知道这一点,但在汇编,我们正在使用没有永久数据类型的物理存储,所以当它重要时,我们通过机器代码指令选择告诉处理器访问有符号或无符号的内存。)

如果您的数据不是 8 位或 16 位宽(或 32 位),您可以使用单个字节,或者从内存中加载比您感兴趣的更多的数据,并清除或符号扩展与您无关的位。

【讨论】:

    【解决方案2】:

    您知道当与+ 等运算符一起使用时,C 是如何将每个窄整数类型隐式提升为int 的吗?该语言设计与 MIPS 之类的体系结构相匹配,这些体系结构本身没有 8 位或 16 位整数运算,只有 int / unsigned int 大小。 (如果您确实使用多条指令来进行扩展精度数学运算,则范围更广)。

    MIPS 指令总是将它们的立即数符号扩展为 32 位。 (或按位布尔指令的零扩展。)

    如果您只关心以后的sb 的低位,则可以使用某些操作而不关心高位,但是像sltbeq 这样的MIPS 比较总是会查看所有位。 Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

    在 C 中,将结果分配给一个窄整数会再次截断结果,这就像在执行 sbsh。 (实际上在 C 中,它将其定义为模减少值以适应类型的值范围,但对于无符号或 2 的补码有符号整数,可以实现为位模式的截断。)

    有关使用 lblbu 将符号或零扩展加载到 32 位的更多 asm 详细信息,另请参阅 Erik 的回答。

    MIPS 的标准调用约定要求窄函数 args 和返回值(如 char foo(short x))正确符号扩展为完整的寄存器宽度,这并非巧合。有关更多信息,请参阅此 x86-64 问题的 MIPS 比较脚注,了解 ISA 如何处理窄数据:MOVZX missing 32 bit register to 64 bit register

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      相关资源
      最近更新 更多