【发布时间】:2021-04-06 21:44:27
【问题描述】:
此程序旨在允许用户将破折号('-' 和 '|')放入框,连接 3x3 网格的顶点。我想知道这个程序如何能够在游戏板上标记动作。在 markMove 部分,这个代码块到底发生了什么:
lb $t0, offset($a0) #Pass $a0 which is integer move 0-9 into offset, then load that data into $t0
#Actually mark now; transfer marker to board through $t1
lb $t1, marker($a0) #Load marker into $t1 after finding corresponding marker
sb $t1, board($t0) #Place the marker at spot in board by storing from $t1
当 $a0 和 $t0 被传递到上面的相应数据类型中时,实际发生了什么?感谢您的帮助。
以下是完整的程序供参考。在 MARS 4.5 上使用 MIPS 组装
.data #Data declaration segment
board: .ascii "\n\n . . . . 0 . 1 ."
.ascii "\n 2 3 4"
.ascii "\n . . . . 5 . 6 ."
.ascii "\n 7 8 9"
.asciiz "\n . . . . a . b .\n"
offset: .byte 6, 8, 33, 35, 37, 62, 64, 89, 91, 93, 118, 120
marker: .byte '-', '-', '|', '|', '|', '-', '-', '|', '|', '|', '-', '-'
.text #Text declaration statement
main:
li $t0, 6 #Number of loops/moves to make; For counting loop. Whatever this is set to will determine number of moves to make
jal loop1
#Print game board
li $v0, 4
la $a0, board
syscall
#Exit Program
li $v0, 10
syscall
loop1:
#Load return address to main onto stack pointer
subu $sp, $sp, 4
sw $ra, ($sp) #Store $ra into $sp
#Inner loop for loop1 is necessary or else return address to main will be infinitely stored.
inner_loop:
#Read integer for marking excluding a and b
li $v0, 5
syscall
move $a0, $v0 #Set $v0 to $a0
jal markMove #Jump to markMove; return address is set in $ra
sub $t0, $t0, 1 #Decrement counter by 1
bnez $t0, inner_loop #Return to L1 if counter not 0
##Cut off point for loop
#Once counter is 0, pop return address off stack pointer
lw $ra, ($sp)
addu $sp, $sp, 4
jr $ra
#Mark a move on the game board
#Input : $a0 (Integer move 0-9)
markMove:
##Prepare to pass necessary variables ($v0, $ra) into function.
subu $sp, $sp, 4 #First must subtract 4 to make space on stack pointer. This must always be done before storing
sw $ra, ($sp) #Store $ra into $sp
subu $sp, $sp, 4 #First must subtract 4 to make space on stack pointer. This must always be done before storing
sw $t0, ($sp) #Store $t0 into $sp
lb $t0, offset($a0) #Pass $a0 which is integer move 0-9 into offset, then load that data into $t0
##Must now check if move has been done already
jal checkMove
beq $v0, 0, loop2 #Pass $v0 into loop2... after loop2, if $v0 = 1 (valid); else $v0 = 0 (invalid)
#Actually mark now; transfer marker to board through $t1
lb $t1, marker($a0) #Load marker into $t1 after finding corresponding marker
sb $t1, board($t0) #Place the marker at spot in board by storing from $t1
#Clear stack pointer ($sp) and return to $ra; $t0 is popped off of $sp; necessary to see if $t0 = 1 or 0 depending on checkMove result
loop2:
##Prepare to take the variables ($t0, $ra) from above.
lw $t0, ($sp) #Pop $t0 off of stack pointer
addu $sp, $sp, 4 #First must add 4 to make space on stack pointer. This must always be done before loading
lw $ra, ($sp) #Pop $ra off of stack pointer
addu $sp, $sp, 4 #First must add 4 to make space on stack pointer. This must always be done before loading
jr $ra #Return to return address; jump register
#Check if a move is valid or not depending on if it has already been done
checkMove:
jr $ra
【问题讨论】:
标签: assembly parameter-passing mips cpu-registers mars-simulator