我只是想检查一下我对这两个概念的理解是否正确,因为我一直在努力完成一个项目,虽然一切都符合我的期望,但它仍然严重地使测试用例失败并引入随机值... < / p>
基本上,该项目的目标是以这种形式写出一个分支指令到控制台:
BranchName $ S,[$ t,如果适用] 0xAbsoluteAddressOfBranchTargetInstruction
编辑:澄清:我是用MIPS写的。我的想法是通过我的讲师代码(我编写函数)获得一个$ a0的内存地址。该地址用于包含MIPS指令的字。我要做以下事情:
IE:
BEQ $ 6,$ 9,0x00100008
首先,我对分支计算的理解是否正确?
其次,有人可以告诉我需要隔离哪些位来知道我正在处理哪种分支?我想我有他们(BEQ / BNE的前6名,其他16名的$ s掩盖了)但我想仔细检查。
哦,最后......我是否应该期望SPIM在Intel x86 Windows系统和Intel x86 Linux系统上运行?我得到了一个愚蠢的故障,我似乎无法将其与我的手工地址计算隔离开来,但它只会在我运行我的教授在Linux上给我们的测试脚本时显示出来(.sh);在任何一个操作系统上直接运行直接运行似乎都有效......前提是我对如何进行手计算(如上所列)的理解是正确的。
答案 0 :(得分:1)
16位立即值符号扩展为32位,然后移位。我不知道这是否会影响你的计划;但是,这是唯一的潜在错误&#34;我注意到了。
答案 1 :(得分:1)
这是我的各种评论的前言。
这是一个正确执行地址计算的示例程序。 不执行分支指令类型解码,因此您必须将此部分和您的版本组合在一起。
请注意,它使用mars
系统调用34以十六进制格式打印值。这在spim
下不可用,因此您可能需要使用系统调用1以十进制输出或编写您自己的十六进制值输出函数[如果您还没有]
.data
msg_best: .asciiz "correct target address: "
msg_tgt: .asciiz "current target address: "
msg_nl: .asciiz "\n"
.text
.globl main
main:
la $s0,inst # pointer to branch instruction
la $s1,einst # get end of instructions
subu $s1,$s1,$s0 # get number of bytes
srl $s1,$s1,2 # get number of instruction words
la $s2,loop # the correct target address
la $a0,msg_best
move $a1,$s2
jal printaddr
loop:
move $a0,$s0
jal showme # decode and print instruction
addiu $s0,$s0,4
sub $s1,$s1,1
bnez $s1,loop # more to do? yes, loop
li $v0,10
syscall
# branch instructions to decode
inst:
bne $s0,$s1,loop
beq $s0,$s1,loop
beqz $s1,loop
bnez $s1,loop
bgtz $s1,loop
bgez $s1,loop
bltz $s1,loop
blez $s1,loop
einst:
# showme -- decode and print data about instruction
#
# NOTE: this does _not_ decode the instruction type
#
# arguments:
# a0 -- instruction address
#
# registers:
# t5 -- raw instruction word
# t4 -- branch offset
# t3 -- absolute address of branch target
showme:
subu $sp,$sp,4
sw $ra,0($sp)
lw $t5,0($a0) # get inst word
addiu $t3,$a0,4 # get PC + 4
sll $t4,$t5,16 # shift offset left
sra $t4,$t4,16 # shift offset right (sign extend)
sll $t4,$t4,2 # get byte offset
addu $t3,$t3,$t4 # add in offset
# NOTE: as a diagnostic, we could compare t3 against s2 -- it should
# always match
la $a0,msg_tgt
move $a1,$t3
jal printaddr
lw $ra,0($sp)
addu $sp,$sp,4
jr $ra
# printaddr -- print address
#
# arguments:
# a0 -- message
# a1 -- address value
printaddr:
li $v0,4
syscall
# NOTE: only mars supports this syscall
# to use spim, use a syscall number of 1, which outputs in decimal and
# then hand convert
# or write your own hex output function
move $a0,$a1
li $v0,34 # output number in hex (mars _only_)
syscall
la $a0,msg_nl
li $v0,4
syscall
jr $ra