不,beq 需要 2 个寄存器并比较它们,仅此而已。请记住,汇编语言反映了机器代码在一条指令中可以做什么。做更复杂的事情通常需要更多的指令。
要将&&多个条件加在一起,你需要任一
第二种方式优化了 C 逻辑具有的短路评估。请注意,在 C 表达式中,如果 a[0] != 'a' 甚至不会访问 a[1],因此即使 a 是指向页面最后一个字节的指针并且下一页未映射,它也不会出错。 (假设a[0] == 0 或其他东西,一个以0 结尾的空字符串)。
但如果你确实知道你可以安全地访问字符串/数组的所有 3 个字节,这是一个选项。
当条件类似于 if (x < 5 && y < 10) 时,作为优化更容易/更有效,您可以使用 2x slti 指令来比较寄存器,然后将这些 reg 放在一起,然后 beq $t0, $zero, skip_if_body
在这种特殊情况下,您要检查 3 个连续字节,它基本上是 memcmp(a, "abc", 3)。
如果你知道a 是字对齐的,你可以做一个字加载来得到你想要的 3 个字节,加上一个我们需要忽略的垃圾字节。
MARS 模拟一个 little-endian MIPS 系统,所以我们想要的 3 个字节是单词中的 3 个最低有效字节。 (一般来说,MIPS 可以按大端或小端运行。)
# assuming a[] is a word-aligned static array
# and little-endian MIPS
lw $t0, a # pseudo-instruction for lui / lw to construct the full address
li $t1, 'abc' << 8 # 0x63626100 if your assemble doesn't like multi-char literals
sll $t0, $t0, 8 # shift out the 4th byte which we need to ignore
bne $t0, $t1, skip_if_body
# if body: a[0] == 'a' && a[1] == 'b' && a[2] == 'c'
...
skip_if_body:
...
jr $ra
如果a 实际上是一个已知字对齐的寄存器中的指针,您当然也可以使用它。 lw $t0, ($a0).
我将不需要的字节从负载中移出,而不是用 AND 屏蔽它,因为 andi 无法编码 0x00FFFFFF。
如果不知道 a 是对齐的,那么对于未对齐的负载,lwl/lwr 可能值得使用。
或者lhu+lbu分别加载16位和8位,如果我们有2字节对齐;如果我们仍然想合并一个分支,我们可以使用xori 一次检查 16 位,利用立即数的全宽。或者只是li/beq。
在寄存器中构造 'abc' << 8 需要 2 条指令(lui + addiu 或 ori)