[英]Trying to understand this MIPS function that branches if its input is negative
我正在阅读以下有关汇编语言代码的摘录:
“可以在组装中使用标签代替计算分支和跳转指令的精确值。以下是示例。”
int isNeg(int a0) {
if (a0 < 0) {
return 1;
} else {
return 0;
}
}
isNeg:
slt $t0 $a0 $0
beq $t0 $0 isPos
jr $ra
isPos:
add $v0 $0 $0
jr $ra
这是我的解释方式(请根据我做的任何错误假设对我进行纠正):
isNeg:
slt $t0 $a0 $0 // store ($a0 < 0) in $t0
beq $t0 $0 isPos // if ($t0 == 0) branch by 0 bytes
jr $ra
isPos:
add $v0 $0 $0 // store 0+0=0 in $v0
jr $ra
因此,如果我的假设在这里是正确的,则如果$ a为负,则不执行任何操作,如果$ a为正,则以0进行分支,这等效于不执行任何操作。 谁能对此有所启发?
谁能对此有所启发?
如果我理解正确,那么这段文字来自一本书。 该示例旨在显示某些指令的效果,而不是显示可以在实际程序中找到的“真实”代码(例如,在具有MIPS CPU的WLAN路由器上)。
这本书的作者唯一想展示的是标签的工作方式,因此他写了一个(愚蠢的)包含标签的示例。
如果$ a为负,我们什么也不做
正确(假设jr $ra
不是真正的MIPS CPU中发现的延迟分支 )
我假设这本书的作者忘记了addi $v0 $0 -1
指令。
beq $t0 $0 isPos
如果$ a是正数,则以0分支
如果beq
是一个延迟分支,这是正确的。
在这种情况下,CPU将首先在beq
或jr
指令之后立即执行该指令,然后才实际进行跳转/跳转。
但是,在这种情况下,在大多数实际的MIPS CPU上,紧随beq
指令之后的jr
指令是不允许的。 因此,我认为这里不是这种情况。
如果使用不模拟延迟槽的仿真器,则beq
指令将跳4个字节(超过jr
指令)。
如果使用真正的MIPS CPU和汇编程序在每个跳转/分支指令(GNU中的.set reorder
选项)后插入nop
指令(例如, add $0 $0 $0
),则beq
指令将跳转8个字节(在jr
指令和nop
指令)。 跳转之后,执行add $v0 $0 $0
指令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.