2016-06-07 51 views
0

我的主程序有問題。我需要允許位傳遞到函數dumpb和dumbw和dumpreg(我認爲)。目前我的輸出是零,但我不認爲這就是我應該得到的。請有人幫助我,或者至少讓我指出我的錯誤所在的正確方向?裝配Mips程序主要電話

.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

我能夠解決您的程序並使其工作,但我不得不做很多返工。

你在堆棧上做了太多的push/pop操作。請注意,儘管代碼在技術上並不是錯誤的[大部分],但這與mips ABI和mips的精神相反,因此很複雜。

您將參數推入堆棧而不是將它們傳遞到寄存器中。這也增加了[不必要的]複雜性。我改變了所有的函數來根據ABI傳遞參數。

你保存那些「被叫擁有」 /恢復寄存器,這意味着被叫不需要保存它們,可以隨意改變他們:V *,A *,T *

在堆棧上保存V0實際因爲它用於返回值[和系統調用號碼],所以會中斷ABI。

你的程序是不完整的(即沒有要轉儲的數組),並且主要是你在調用函數時沒有爲它們設置參數。

我簡化了真正的低級功能,如prchar。請特別注意,調用它的單個字符輸出函數(例如prnl)現在使用「尾部調用優化」,因此它們不需要自己的堆棧框架。

我更改了​​預先存儲了regs,然後調用dumpw而不是複製代碼。

我離開了你的prwordprbyte功能完好[它們不再使用]。如果要使用它們,請考慮刪除它們仍具有的「push arg on stack」接口,並轉換爲使用$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