本组装MIPS中的Nop和管道危险

时间:2014-01-04 17:48:25

标签: assembly mips

在通过Cross Compiler编译C到汇编MIPS之后,我得到了:

main:
.frame $fp,32,$31 # vars= 16, regs= 1/0, args= 0, gp= 8

addiu $sp,$sp,-32
sw $fp,24($sp)
move $fp,$sp
li $2,5 # 0x5
sw $2,8($fp)
lw $2,8($fp)
nop
sw $2,16($fp)
li $2,5 # 0x5
lw $3,16($fp)
nop
beq $3,$2,$L4
nop

li $2,10 # 0xa
lw $3,16($fp)
nop
beq $3,$2,$L5
nop

li $2,1 # 0x1
lw $3,16($fp)
nop
beq $3,$2,$L3
nop

b $L7
nop

$L3:
lw $2,8($fp)
nop
addiu $2,$2,3
sw $2,8($fp)
b $L7
nop

$L4:
lw $2,8($fp)
nop
sll $2,$2,3
sw $2,8($fp)
b $L7
nop

$L5:
lw $2,8($fp)
nop
srl $2,$2,2
sw $2,8($fp)
$L7:
move $sp,$fp
lw $fp,24($sp)
addiu $sp,$sp,32
j $31
nop

.end main

我不明白为什么有很多nop代码行,这段代码中nop的含义是什么?它对Pipeline Hazards中的任何内容有帮助吗?如果我删除所有的n ??

2 个答案:

答案 0 :(得分:2)

由于管道危险,

NOP被插入。

回想一下,MIPS管道由5个阶段组成:Fetch,Decode,eXecute,Memory,Write-back。

让我们来看看NOP。第一个是:

lw $2,8($fp)
nop
sw $2,16($fp)

此代码假定没有内存 - 内存转发。为什么?因为如果你绘制一个时间线管道图,你会看到NOP迫使sw的内存阶段在lw的回写阶段后的一个周期内发生。因此,代码假定处理器具有存储器 - &gt; ALU转发或回写 - &gt;内存转发。如果我们之间没有使用NOPsw的内存阶段会从$2读取一些垃圾值(无论来自解码阶段),行为都是未定义的。< / p>

第二个nop

lw $3,16($fp)
nop
beq $3,$2,$L4

此处,$3仅在lw的Memory阶段结束后可用。如果我们没有NOP,那么beq eXecute阶段将发生在与lw的内存阶段相同的周期中,即使使用内存也是如此 - &gt; ALU转发。因此,我们必须延迟beq一个周期,这就是NOP正在做的事情。使用此NOPbeq的执行阶段将在lw的内存后一个周期发生。这是有效的,假设有记忆 - &gt; ALU转发。

类似的原因也适用于其他情况,我建议你自己解决这个问题。

答案 1 :(得分:2)

根据您的代码添加所有'nop'指令以修复以下错误

1)分支延迟

2)负载延迟

因为这些nop是由编译器添加的,你可以明确地给编译器一个选项,让我们不要通过“set noreorder”更好地添加这些nop指令。我应该给你参考read。 “请参阅Mips Run 2nd Edition”页面编号我并没有看到'nop'是危险屏障。按照这本书。