我的主程序遇到问题。我需要允许位传递到函数dumpb和dumbw和dumpreg(我认为)。目前我的输出为零,但我不认为这是我应该得到的。有人可以帮助我,或者至少指出我错误的方向吗?
.data
n_elem: .word 10
.text
.globl main
main:
jal dumpreg
jal prword
jal prchar
#insert element to dump
jal dumpb
#insert element to dump
jal dumpw
addi $v0, $0, 10 #exit program
syscall
dumpw:
addi $sp, $sp, -16 #allocates memory
sw $a0, 12($sp)
sw $v0, 8($sp)
sw $t0, 4($sp)
sw $t1, 0($sp)
lw $t0, 20($sp) # load n_elem
lw $t1, 16($sp) # load address
looptop:
beq $t0, $0, bailout
lw $a0, 0($t1) # a0 = address[i]
addi $v0, $0, 1
syscall
addi $t0, $t0, -1
addi $t1, $t1, 4
j looptop
bailout:
lw $t1, 0($sp)
lw $t0, 4($sp)
lw $v0, 8($sp)
lw $a0, 12($sp)
addi $sp, $sp, 16
jr $ra
dumpb:
addi $sp, $sp, -16
sw $a0, 12($sp)
sw $v0, 8($sp)
sw $t0, 4($sp)
sw $t1, 0($sp)
lw $t0, 20($sp) # load n_elem
lw $t1, 16($sp) # load address
looptopb:
beq $t0, $0, bailoutb
lb $a0, 0($t1) # a0 = address[i]
addi $v0, $0, 11
syscall
addi $t0, $t0, -1
addi $t1, $t1, 1
j looptopb
bailoutb:
lw $t1, 0($sp)
lw $t0, 4($sp)
lw $v0, 8($sp)
lw $a0, 12($sp)
addi $sp, $sp, 16
jr $ra
prspace:
addi $sp, $sp, -8
sw $a0, 0($sp)
sw $ra, 4($sp)
addi $a0, $0, ' '
addi $sp, $sp, -4 #push it
sw $a0, 0($sp)
jal prchar
addi $sp, $sp, 4
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
prcomma:
addi $sp, $sp, -8
sw $a0, 0($sp)
sw $ra, 4($sp)
addi $a0, $0, ',' #
addi $sp, $sp, -4 #push it
sw $a0, 0($sp)
jal prchar
addi $sp, $sp, 4
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
prnl:
addi $sp, $sp, -8
sw $a0, 0($sp)
sw $ra, 4($sp)
addi $a0, $0, 0x0A # 0xA new line char
addi $sp, $sp, -4 #push it
sw $a0, 0($sp)
jal prchar
addi $sp, $sp, 4
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
prchar:
addi $sp, $sp, -8
sw $a0, 4($sp)
sw $v0, 0($sp)
lw $a0, 8($sp)
addi $v0, $0, 11
syscall
lw $v0, 0($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8
jr $ra
prbyte:
addi $sp, $sp, -8
sw $a0, 4($sp)
sw $v0, 0($sp)
lw $a0, 8($sp)
addi $v0, $0, 1
syscall
lw $v0, 0($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8
jr $ra
dumpreg:
addi $sp, $sp, -4
sw $ra, 0($sp)
jal prnl
addi $sp, $sp, -4
jal prspace
sw $a0, 0($sp)
jal prword
jal prspace
sw $a1, 0($sp)
jal prword
jal prspace
sw $t0, 0($sp)
jal prword
jal prspace
sw $t1, 0($sp)
jal prword
jal prspace
sw $t2, 0($sp)
jal prword
jal prspace
sw $t3, 0($sp)
jal prword
jal prspace
sw $t4, 0($sp)
jal prword
jal prspace
sw $s0, 0($sp)
jal prword
jal prspace
sw $s1, 0($sp)
jal prword
addi $sp, $sp, 4
jal prnl
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
prword:
addi $sp, $sp, -8
sw $a0, 4($sp)
sw $v0, 0($sp)
lw $a0, 8($sp)
addi $v0, $0, 1
syscall
lw $a0, 4($sp)
lw $v0, 0($sp)
addi $sp, $sp, 8
jr $ra
答案 0 :(得分:1)
我能够修复你的程序并使其正常工作,但我不得不做一些返工。
你在堆栈上做了太多的推/弹。请注意,虽然代码在技术上并不是[大多数],但它与mips ABI和mips的精神相反,因此很复杂。
您正在将参数推送到堆栈而不是将它们传递到寄存器中。这也增加了[不必要的]复杂性。我根据ABI改变了所有函数来传递参数。
您正在保存/恢复被叫"被叫方拥有的注册表#34;这意味着被叫方无需保留它们并可随意更改它们:v *,a *,t *
在堆栈上保存v0实际上会破坏ABI,因为它用于返回值[和系统调用号码]。
您的程序不完整(即没有要转储的数组),并且在main中,您在调用函数时没有为它们设置参数。
我简化了prchar
等真正的低级功能。请特别注意,调用它的单个字符输出函数(例如prnl
)现在使用"尾调用优化",因此它们不需要自己的堆栈帧。 / p>
我更改dumpregs
预先存储了regs,然后调用dumpw
而不是复制代码。
我完全保留了prword
和prbyte
个功能[不再使用它们]。如果你想使用它们,可以考虑删除堆栈上的" push arg"他们仍然拥有的界面,转而使用$a0
代替。
所以,代码可能看起来[相当]对你有点陌生[请原谅无偿的风格清理]:
.data
n_elem: .word 10
array: .word 1,2,3,4,5,6,7,8,9,10
dumpw_msg: .asciiz "words:"
dumpb_msg: .asciiz "bytes:"
dumpreg_msg: .asciiz "regs:"
.text
.globl main
main:
jal prnl
jal dumpreg
# dump array as words
la $a0,dumpw_msg
li $v0,4
syscall
la $a0,array
lw $a1,n_elem
jal dumpw
# dump array as bytes
la $a0,dumpb_msg
li $v0,4
syscall
la $a0,array
lw $a1,n_elem
sll $a1,$a1,2 # get byte count
jal dumpb
addi $v0,$0,10 # exit program
syscall
# dumpw -- dump array as words
#
# arguments:
# a0 -- pointer to array
# a1 -- number of words in array
dumpw:
move $t1,$a0 # load address
move $t0,$a1 # load count
dumpw_loop:
ble $t0,$0,dumpw_done
# output a space
addi $v0,$0,11
addi $a0,$0,' '
syscall
lw $a0,0($t1) # a0 = address[i]
addi $v0,$0,1
syscall
addi $t0,$t0,-1
addi $t1,$t1,4
j dumpw_loop
dumpw_done:
# output a newline
addi $v0,$0,11
addi $a0,$0,0x0a
syscall
jr $ra
# dumpb -- dump array as bytes
#
# arguments:
# a0 -- pointer to array
# a1 -- number of bytes in array
dumpb:
move $t1,$a0 # load address
move $t0,$a1 # load count
dumpb_loop:
ble $t0,$0,dumpb_done
# output a space
addi $v0,$0,11
addi $a0,$0,' '
syscall
lb $a0,0($t1) # a0 = address[i]
addi $v0,$0,1
syscall
addi $t0,$t0,-1
addi $t1,$t1,1
j dumpb_loop
dumpb_done:
# output a newline
addi $v0,$0,11
addi $a0,$0,0x0a
syscall
jr $ra
# dumpreg -- dump registers
dumpreg:
addi $sp,$sp,-36
sw $ra,0($sp)
# pre-store the registers we wish to dump
sw $a0,4($sp)
sw $a1,8($sp)
sw $t0,12($sp)
sw $t1,16($sp)
sw $t2,20($sp)
sw $t3,24($sp)
sw $s0,28($sp)
sw $s1,32($sp)
# output the identifying message
la $a0,dumpreg_msg
li $v0,4
syscall
# now, because of the pre-store, we can reuse the array dumper
addiu $a0,$sp,4 # point to the dumped registers array
addi $a1,$0,8 # get number of words to dump
jal dumpw
# restore the dumped register values
lw $a0,4($sp)
lw $a1,8($sp)
lw $t0,12($sp)
lw $t1,16($sp)
lw $t2,20($sp)
lw $t3,24($sp)
lw $s0,28($sp)
lw $s1,32($sp)
lw $ra,0($sp)
addi $sp,$sp,36
jr $ra
# prword -- dump a word as integer (currently unused)
prword:
addi $sp,$sp,-8
sw $a0,4($sp)
sw $v0,0($sp)
lw $a0,8($sp)
addi $v0,$0,1
syscall
lw $a0,4($sp)
lw $v0,0($sp)
addi $sp,$sp,8
jr $ra
# prbyte -- print a byte (currently unused)
prbyte:
addi $sp,$sp,-8
sw $a0,4($sp)
sw $v0,0($sp)
lw $a0,8($sp)
addi $v0,$0,1
syscall
lw $v0,0($sp)
lw $a0,4($sp)
addi $sp,$sp,8
jr $ra
# prspace -- print a space
prspace:
addi $a0,$0,' '
j prchar
# prcomma -- print a comma
prcomma:
addi $a0,$0,','
j prchar
# prnl -- print a newline
prnl:
addi $a0,$0,0x0A
j prchar
# prchar -- print an ascii char
prchar:
addi $v0,$0,11
syscall
jr $ra