在MIPS中编写子程序,将整数0到15转换为ASCII字符' 0'通过' F'

时间:2017-02-15 14:53:18

标签: assembly mips

写一个小子程序,将0到15范围内的数字转换成a 可打印的ASCII编码字符:' 0'通过' 9'或者' A'通过' F',取决于号码。 对于不在0到15范围内的数字,将忽略某些位。

名称:子程序必须被称为hexasc。 参数:一,寄存器$ a0。 4个最低有效位指定一个从0到15的数字。 寄存器$ a0中的所有其他位可以具有任何值,必须忽略。 返回值:寄存器$ v0中的7个最低有效位必须是ASCII码,如下所述。 函数返回时,所有其他位必须为零。 必需的操作:该函数必须将输入值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

2 个答案:

答案 0 :(得分:0)

一些问题......

您在十进制测试期间销毁了$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

答案 1 :(得分:0)

这两篇文章中有一个值得一提的小错误,rootRoute应为li $v0,0x41。这是由于您的规范指出,li $v0,0x7的输入值应打印出ASCII中的字符10,但如果您有A,则输出将为li $v0,0x41而不是{{} 1}}输入值为K。 以下是A的另一个版本,其中列出了您在规范中所说的内容。

10