在 MIPS 中编写子程序,将整数 0 到 15 转换为 ASCII 字符“0”到 'F'
Write subroutine in MIPS that convert integer 0 through 15 into ASCII character '0' through 'F'
编写一个小子程序,将 0 到 15 范围内的数字转换为
可打印的 ASCII 编码字符:“0”到“9”,或 'A' 到 'F',具体取决于数字。
对于不在 0 到 15 范围内的数字,某些位将被忽略。
名称:子例程必须命名为 hexasc 。
参数:1,在寄存器 $a0 中。 4 个最低有效位指定一个数字,从 0 到 15。
寄存器 $a0 中的所有其他位可以具有任何值并且必须被忽略。
Return 值:寄存器 $v0 中的 7 个最低有效位必须是如下所述的 ASCII 码。
当您的函数 returns 时,所有其他位必须为零。
所需操作:该函数必须将输入值 0 到 9 转换为数字的 ASCII 代码
分别为“0”到“9”。输入值 10 到 15 必须转换为 ASCII 代码
字母 'A' 到 'F'。
.text
main:
li $a0,0 # change this to test different values
jal hexasc # call hexasc
nop # delay slot filler (just in case)
move $a0,$v0 # copy return value to argument register
li $v0,11 # syscall with v0 = 11 will print out
syscall # one byte from a0 to the Run I/O window
stop: j stop # stop after one run
nop # delay slot filler (just in case)
我在这里写了我的 hexasc
子例程,但由于某些我不理解的原因,所以它不起作用。我无法弄清楚我在哪一部分有错误,也许我没有按照上面的规范中所说的那样做。
任何帮助将不胜感激,提前致谢。
hexasc:
addi $sp,$sp,-4 #make space on the stack
sw $a0,0($sp) #store $a0 on the stack
li $t0,0x30 #$t0 = 0x30 ('0' in ascii)
andi $a0,$a0,0xf #only 4 least significant bits is
#needed ignore other bits
loop:
add $a0,$a0,$t0 #$a0 i will think why i did this
addi $t0,$t0,1 #increment $t0 by 1
beq $t0,0x39,loop2 # if $t0 = 0x39 (9 in ascii)
j loop
li $t1,0x41 # $t1 = 0x41 ( A in ascii)
loop2:
andi $a0,$a0,0xf # only 4 LSB ignore other bits
add $a0,$a0,$t1 # ???? i will think about this
beq $t1,0x46,done # if $t1 = 0x46 (F in ascii)
j loop2
done:
add $v0,$a0,$a0 # return $a0 in $v0 suspicious ...?
lw $a0,0($sp) # restore the $a0
addi $sp,$sp,4 # put back the stack
jr $ra
几个问题...
您在十进制测试期间破坏了 $a0
值,因此十六进制部分的值错误。
你的跳跃在做 [无限] 循环。他们应该去 done:
我已经为您的代码创建了两个版本。一个带有注释,一个带有更正的代码[请原谅不必要的样式清理]。
这是注释版本:
hexasc:
# NOTE/BUG: stack save/restore of $a0 is not needed due to MIPS ABI
addi $sp,$sp,-4 # make space on the stack
sw $a0,0($sp) # store $a0 on the stack
li $t0,0x30 # $t0 = 0x30 ('0' in ascii)
andi $a0,$a0,0xf # only 4 least significant bits is
# needed ignore other bits
# NOTE/BUG: altering $a0 further destroys the value for the hex test
loop:
add $a0,$a0,$t0 # $a0 i will think why i did this
addi $t0,$t0,1 # increment $t0 by 1
# NOTE/BUG: beq is wrong -- we want bgt
# NOTE/BUG: the range test for decimal should be 0x09 and _not_ 0x39
beq $t0,0x39,loop2 # if $t0 = 0x39 (9 in ascii)
# NOTE/BUG: looping is wrong -- this should be 'j done'
j loop
li $t1,0x41 # $t1 = 0x41 ( A in ascii)
# NOTE/BUG: $a0 is now wrong because of add above
loop2:
andi $a0,$a0,0xf # only 4 LSB ignore other bits
add $a0,$a0,$t1 # ???? i will think about this
# NOTE/BUG: no range check needed as all values are in range
beq $t1,0x46,done # if $t1 = 0x46 (F in ascii)
# NOTE/BUG: no looping required
j loop2
done:
add $v0,$a0,$a0 # return $a0 in $v0 suspicious ...?
lw $a0,0($sp) # restore the $a0
addi $sp,$sp,4 # put back the stack
jr $ra
这是更正后的版本:
hexasc:
andi $a0,$a0,0xf # only 4 least significant bits is needed
# check for decimal
li $v0,0x30 # set 0x30 ('0' in ascii)
ble $a0,0x09,hexasc_done # value in range 0x0-0x9? if yes, fly
li $v0,0x41 # set 0x41 ('A' in ascii)
hexasc_done:
add $v0,$v0,$a0 # convert value to ascii
jr $ra
这两篇文章有一个小bug值得一提,li $v0,0x41
应该是li $v0,0x7
。这是由于您的规范 10
的输入值应该以 ASCII 打印出字符 A
,但是如果您有 li $v0,0x41
,则输出将是 K
而不是 A
用于输入值 10
。
这是 hexasc
的另一个版本,它打印出您的规格中的 Say。
hexasc:
andi $a0,$a0,0x0f
addi $v0,$zero,0x30
addi $t0,$zero,0x9
ble $a0,$t0,L1
nop
addi $v0,$v0,0x7
L1:
add $v0,$a0,$v0
jr $ra
nop
编写一个小子程序,将 0 到 15 范围内的数字转换为 可打印的 ASCII 编码字符:“0”到“9”,或 'A' 到 'F',具体取决于数字。 对于不在 0 到 15 范围内的数字,某些位将被忽略。
名称:子例程必须命名为 hexasc 。 参数:1,在寄存器 $a0 中。 4 个最低有效位指定一个数字,从 0 到 15。 寄存器 $a0 中的所有其他位可以具有任何值并且必须被忽略。 Return 值:寄存器 $v0 中的 7 个最低有效位必须是如下所述的 ASCII 码。 当您的函数 returns 时,所有其他位必须为零。 所需操作:该函数必须将输入值 0 到 9 转换为数字的 ASCII 代码 分别为“0”到“9”。输入值 10 到 15 必须转换为 ASCII 代码 字母 'A' 到 'F'。
.text
main:
li $a0,0 # change this to test different values
jal hexasc # call hexasc
nop # delay slot filler (just in case)
move $a0,$v0 # copy return value to argument register
li $v0,11 # syscall with v0 = 11 will print out
syscall # one byte from a0 to the Run I/O window
stop: j stop # stop after one run
nop # delay slot filler (just in case)
我在这里写了我的 hexasc
子例程,但由于某些我不理解的原因,所以它不起作用。我无法弄清楚我在哪一部分有错误,也许我没有按照上面的规范中所说的那样做。
任何帮助将不胜感激,提前致谢。
hexasc:
addi $sp,$sp,-4 #make space on the stack
sw $a0,0($sp) #store $a0 on the stack
li $t0,0x30 #$t0 = 0x30 ('0' in ascii)
andi $a0,$a0,0xf #only 4 least significant bits is
#needed ignore other bits
loop:
add $a0,$a0,$t0 #$a0 i will think why i did this
addi $t0,$t0,1 #increment $t0 by 1
beq $t0,0x39,loop2 # if $t0 = 0x39 (9 in ascii)
j loop
li $t1,0x41 # $t1 = 0x41 ( A in ascii)
loop2:
andi $a0,$a0,0xf # only 4 LSB ignore other bits
add $a0,$a0,$t1 # ???? i will think about this
beq $t1,0x46,done # if $t1 = 0x46 (F in ascii)
j loop2
done:
add $v0,$a0,$a0 # return $a0 in $v0 suspicious ...?
lw $a0,0($sp) # restore the $a0
addi $sp,$sp,4 # put back the stack
jr $ra
几个问题...
您在十进制测试期间破坏了 $a0
值,因此十六进制部分的值错误。
你的跳跃在做 [无限] 循环。他们应该去 done:
我已经为您的代码创建了两个版本。一个带有注释,一个带有更正的代码[请原谅不必要的样式清理]。
这是注释版本:
hexasc:
# NOTE/BUG: stack save/restore of $a0 is not needed due to MIPS ABI
addi $sp,$sp,-4 # make space on the stack
sw $a0,0($sp) # store $a0 on the stack
li $t0,0x30 # $t0 = 0x30 ('0' in ascii)
andi $a0,$a0,0xf # only 4 least significant bits is
# needed ignore other bits
# NOTE/BUG: altering $a0 further destroys the value for the hex test
loop:
add $a0,$a0,$t0 # $a0 i will think why i did this
addi $t0,$t0,1 # increment $t0 by 1
# NOTE/BUG: beq is wrong -- we want bgt
# NOTE/BUG: the range test for decimal should be 0x09 and _not_ 0x39
beq $t0,0x39,loop2 # if $t0 = 0x39 (9 in ascii)
# NOTE/BUG: looping is wrong -- this should be 'j done'
j loop
li $t1,0x41 # $t1 = 0x41 ( A in ascii)
# NOTE/BUG: $a0 is now wrong because of add above
loop2:
andi $a0,$a0,0xf # only 4 LSB ignore other bits
add $a0,$a0,$t1 # ???? i will think about this
# NOTE/BUG: no range check needed as all values are in range
beq $t1,0x46,done # if $t1 = 0x46 (F in ascii)
# NOTE/BUG: no looping required
j loop2
done:
add $v0,$a0,$a0 # return $a0 in $v0 suspicious ...?
lw $a0,0($sp) # restore the $a0
addi $sp,$sp,4 # put back the stack
jr $ra
这是更正后的版本:
hexasc:
andi $a0,$a0,0xf # only 4 least significant bits is needed
# check for decimal
li $v0,0x30 # set 0x30 ('0' in ascii)
ble $a0,0x09,hexasc_done # value in range 0x0-0x9? if yes, fly
li $v0,0x41 # set 0x41 ('A' in ascii)
hexasc_done:
add $v0,$v0,$a0 # convert value to ascii
jr $ra
这两篇文章有一个小bug值得一提,li $v0,0x41
应该是li $v0,0x7
。这是由于您的规范 10
的输入值应该以 ASCII 打印出字符 A
,但是如果您有 li $v0,0x41
,则输出将是 K
而不是 A
用于输入值 10
。
这是 hexasc
的另一个版本,它打印出您的规格中的 Say。
hexasc:
andi $a0,$a0,0x0f
addi $v0,$zero,0x30
addi $t0,$zero,0x9
ble $a0,$t0,L1
nop
addi $v0,$v0,0x7
L1:
add $v0,$a0,$v0
jr $ra
nop