Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly MIPS分支执行指令(beqz)_Assembly_Branch_Mips - Fatal编程技术网

Assembly MIPS分支执行指令(beqz)

Assembly MIPS分支执行指令(beqz),assembly,branch,mips,Assembly,Branch,Mips,我在理解代码中的指令顺序时遇到了一些问题。让我们假设beqz为真,它分支到label next,程序是否在那里结束,或者label next2是否也执行?因为没有系统调用来结束程序 add $t0,$t1,$t2 beqz $t0, next b next2 addi $t0,$t0,2 next: addi $t2,$t0,3 next2: addi $t1,$t1,2 该计划将在next2继续进行。我假设您希望在分支为true时跳过next2,因此您可以按以下操

我在理解代码中的指令顺序时遇到了一些问题。让我们假设beqz为真,它分支到label next,程序是否在那里结束,或者label next2是否也执行?因为没有系统调用来结束程序

add $t0,$t1,$t2

beqz $t0, next

b next2

addi $t0,$t0,2

next: 
   addi $t2,$t0,3

next2: 
    addi $t1,$t1,2

该计划将在next2继续进行。我假设您希望在分支为true时跳过next2,因此您可以按以下操作修复它:

add $t0,$t1,$t2

beqz $t0, next

b next2

addi $t0,$t0,2

next: 
   addi $t2,$t0,3
   b cont

next2: 
    addi $t1,$t1,2

cont:
    # The rest of your program ...

标签只是让您引用另一条指令中的地址的一种方式。他们不会阻止执行。无论源代码中是否有空格或标签,执行始终持续到下一条指令

记住,asm源代码只是一种将机器代码放入文件的语言;标签不会出现在机器代码中


你的代码很奇怪。在
b
指令之后有一个
addi$t0,$t0,2
,因此在禁用分支延迟槽的情况下永远无法到达该指令。(MARS/SPIM的默认设置)。它上面没有标签,所以它不是你从别处跳转到的分支目标

但是,如果您使用的是带有分支延迟槽的真实MIPS(即使执行了分支,分支后的指令也会执行),则
b
位于
beq
的分支延迟槽中。i、 e.
b
将运行分支,无论分支是否被执行,这使得它毫无意义。所以你的代码在任何方面都没有意义


您正在使您的
if
变得更加复杂(或者它是
if/else
?)不要使用
beq
/
b
总是跳转到某个地方,只需使用
bne
跳转或跳转即可。
此外,还可以使用有意义的标签名称

无分支延迟插槽的MIPS 添加$t0、$t1、$t2 bnez$t0,和非零 #addi$t0,$t0,2#无法访问,还是应该是一个分支延迟槽? #sumzero:#不是真正的分支目标,只能通过故障检修实现 addi$t2,$zero,3#仅在t0=0时到达,甚至可能不阅读它 #像往常一样,执行一直到下一条指令 和非零: addi$t1,$t1,2#运行是否使用bnez ... 继续执行 或者在具有分支延迟时隙的MIPS上,假设
addi$t0,$t0,2
仅在
$t0
为非零时运行

我正在用fall-through路径中的
addi$t1,$t1,2
填充分支延迟槽,因为它总是在原始源代码中运行。我想这是有意的

    add  $t0, $t1,$t2
    bnez $t0, sum_nonzero
    addi $t1,$t1,2       # branch-delay: runs whether bnez was taken or not

# Fall through when sum == zero
    addi  $t2, $zero, 3
    addiu $t0,$zero, -2     # instead of branching to avoid addi  $t0,$t0,2 on this path, do its inverse

sum_nonzero: 
    addi  $t0,$t0,2         # produces $t0 = 0 if $t1+$t2 == 0, otherwise $t0 = $t1+$t2+2

    ... execution continues

如果您正在制作一个
If
/
else
,您可以将代码放在另一侧的某个地方(在
jr$ra
返回之后),这样您就不必跳过它。因此,一条路径有一个未执行的分支;另一方有一个take
beq
和一个无条件的
b
来重新加入另一条路径。

“程序是否在那里结束?”否。“或者标签next2是否也执行?”是。您的示例还有另一个问题:如果分支指令紧跟在另一条之后(
b
紧跟在
beqz
)MIPS CPU的结果未定义。至少MIPS R4000 CPU的手册上有这样的说明。在这种情况下,通常汇编程序会在跳转之间隐式添加一条
nop
指令。@Michael好的,谢谢你,我想我知道了。加法后返回beqz,再次检查,但现在它为假,所以它进入下一个2,进行加法,然后进入b下一个2的加法,然后结束。@MartinRosenau谢谢你的更正,这只是课堂上的一个例子,你可以怪我的教授lol@MartinRosenau:根据我的经验,在学术界教授MIPS组装时,他们倾向于使用类似SPIM或MARS的模拟器。默认情况下,这些延迟了分支功能的禁用,可能是为了让学生们的事情变得不那么复杂。我迟到了一年多,但谢谢你的帮助。代码不是我写的,所以怪我的教授太奇怪了。@user2602540:请随意给你的教授发一个链接,链接到这个答案:P