Mips 如何将jr$ra直接放置到正确的位置?

Mips 如何将jr$ra直接放置到正确的位置?,mips,qtspim,Mips,Qtspim,我想跳到打印组件,但现在我写了这段代码,它显示了 尝试在0x00400324执行非指令 在QTspim中。我希望我能学会如何放置它 另外,我不能跳转print10,但可以跳转print8 因为在str2int中使用了jr$ra。请告诉我为什么,我很感激。 这是我的密码: # ---------------------------------- # Data Segment .data msg: .ascii "Info: the inputted 32-bit unsigned numb

我想跳到打印组件,但现在我写了这段代码,它显示了

尝试在0x00400324执行非指令

在QTspim中。我希望我能学会如何放置它

另外,我不能跳转
print10
,但可以
跳转print8
因为在
str2int
中使用了
jr$ra
。请告诉我为什么,我很感激。 这是我的密码:

# ----------------------------------
# Data Segment
.data
msg:    .ascii  "Info: the inputted 32-bit unsigned number can be binary with prefix \"b\",\n"
        .ascii  "\t\t\t     or octal with prefix \"0\",\n"
        .ascii  "\t\t\t     or decimal without prefix,\n"
        .asciiz "\t\t\t     or hexadecimal with prefix\"0x\".\n"

prompt: .asciiz "\nEnter a number: "
ansBin: .asciiz "Convert it to Binary: b"
ansDec: .asciiz "Convert it to Decimal: "
ansOct: .asciiz "Convert it to Octal: 0"
ansHex: .asciiz "Convert it to Hexadecimal: 0x"
comp:   .asciiz "\nDo you wanna continue(y/n)? \n"
newLine:    .asciiz "\n"
end:    .asciiz "\nEnd\n"
buffer: .space  33

# ----------------------------------
# Text/Code Segment

.text
.globl main
main:
    la  $a0, msg    # print msg
    li  $v0, 4
    syscall

print_promt:
    la  $a0, prompt # print prompt
    li  $v0, 4
    syscall

    la  $a0, buffer # this is the input $a0 is the whole thing eg.b10100
    li  $a1, 33     # the length of a1 is 33
    li  $v0, 8      # read String
    syscall

    lb      $s0, 0($a0) # $s0 is the first char
                        # Each character is a byte long
                        # now $s0 = 1st char

    bne     $s0, 98, notBin # 98 is 'b' in ASCII code

    addi    $a0, $a0, 1 # check 2nd char ( no b,0,0x )
                        # now $s0 = 2nd char
    lb      $s0,0($a0)
    move    $s1, $s0
    li      $t5, 2      # binary ($a2 = 2)

endofnotBin:
    # ----- Binary to Decimal ----- 
    jal     str2int         # go str2int, Binary to Decimal
    add     $t6, $v1, $zero # keep fot print10  
    move    $a2, $v1        # $v1 is the ans of Decimal
                            # Octal starts with $a2
    jal print10
    # ----- End -----       

#--------------------------------------------------------
    # ----- Decimal to Octal -----  
    jal print8
    move    $a2, $v1
    # ----- End -----   

    # ----- Just print Decimal -----
    jal print10
    move    $a2, $v1
    # ----- End -----   

    # ----- Decimal to Hexadecimal -----
    jal print16

#--------------------------------------------------------

    # ------------- ENDING -------------    
print_comp:
    la  $a0, comp       # print comp
    li  $v0, 4          # print String
    syscall

    la  $a0, buffer
    li  $a1, 33         # length of a1 is 33
    li  $v0, 8          # read integer, a place to write Y/N
    syscall

    lb  $s0, 0($a0)
    beq $s0, 89, print_promt        # if input "Y" (89 is Y in ASCII) go print_promt
    beq $s0, 121, print_promt       # if input "y" (121 is y in ASCII) go print_promt

    beq $s0, 78, theend     # if input "N" (78 is N in ASCII) go theend
    beq $s0, 110, theend    # if input "n" (110 is n in ASCII) go theend

theend:
    la  $a0, end        # print end
    li  $v0, 4
    syscall

    # -----
    # Done, exit program.
    li      $v0, 10         # call code for exit
    syscall                 # system call

#--------------------------------------------------------------------
notBin: # TODO
    beq $s0, 48, isOct  # 48 is '0' in ASCII code
    beq $s0, 49, isDex  # 49 is '1' in ASCII code
    beq $s0, 50, isDex  # 50 is '2' in ASCII code
    beq $s0, 51, isDex  # 51 is '3' in ASCII code
    beq $s0, 52, isDex  # 52 is '4' in ASCII code
    beq $s0, 53, isDex  # 53 is '5' in ASCII code
    beq $s0, 54, isDex  # 54 is '6' in ASCII code
    beq $s0, 55, isDex  # 55 is '7' in ASCII code
    beq $s0, 56, isDex  # 56 is '8' in ASCII code
    beq $s0, 57, isDex  # 57 is '9' in ASCII code

isOct:
    addi    $a1,$a0,1
    lb      $s0,0 ($a1)
    bne     $s0, 120, isHex     # 120 is 'x' in ASCII code
    lb      $s0,0 ($a0)
    jal     print2
    j       endofnotBin

isHex:
    addi    $a0,$a0,1           # start to read 3rd code permently
    lb      $s0,0 ($a0)         # load new $s0
    jal     print2

    j       endofnotBin

#--------Whem the prefix is Decimal ---------   
isDex:
    # ----- Decimal to Binary -----
    jal print2
    add     $t5, $zero, $a0     # copy one for Octal and Hexadecimal
    add     $t0, $zero, $a0     # $t0 = $a0
    add     $t1, $zero, $zero   # $t1 = 0
    addi    $t3, $zero, 1       # $t3 = 1
    sll     $t3, $t3, 31        # move the mask
    addi    $t4, $zero, 32      # count the loop

loop12:
    and     $t1, $t0, $t3       # and the input with the mask
    beq     $t1, $zero, print12     # Branch to print if its 0

    add     $t1, $zero, $zero   # Zero out $t1
    addi    $t1, $zero, 1       # Put a 1 in $t1
    j print12


print12: 
    li   $v0, 1
    move $a0, $t1
    syscall

    srl  $t3, $t3, 1
    addi $t4, $t4, -1
    bne  $t4, $zero, loop12

    # ----- Decimal to Octal -----
    move $a2,$t5

    jal print8
    move    $a2, $v1
    # ----- Decimal to Hexadecimal -----
    jal print16

    j   print_comp
    j   endofnotBin
#--------Whem the prefix is Decimal ---------   


.end main

# ----------
# procedure: str2int
# $a0 = starting address of input string excluding prefix
# $a2 = base
# return value = $v1
# -------------------------------------------------------------------------
.globl str2int
str2int:
    lb      $s0, 0($a0) # beacuse $a0 + 1 in Line 44 
                        # $s0 now read the 2nd char (num)
                        # and count the length from 2nd - end
    move    $a1, $a0    # $a1 ← $a0 = ($a0 + 1)

#----↓↓↓------------------------------------------------------------------
length: 
    lb      $s0, 0($a1)     # $s0 = 0 + $a1
                            # $s0 = 0 + ($a1 + 1) in second time
    beq     $s0, 10, endString #if $s0 = 10 (new line in ASCII) , go endString
    addi    $a1, $a1, 1     # $a1 = $a1 + 1
    j       length          # looping $a1 + 1 to chack every character
#----↓↓↓------------------------------------------------------------------
endString:
    sub     $t3, $a1, $a0   # new $t3 =  $a1(length of String except char) - $a0( first char / 1 )
    # $a1 is the length of input digits
    # ("length to endString" is a way to find the length)
    add     $t4, $zero, $t3
    li      $t1,1   # $t1 = 1
    li      $v0,1   # $v0 = 1
    li      $v1,0   # $v1 = 0
    li      $s2,0   # $s2 = 0
    li      $t0,0   # $t0 = 0   
#----↓↓↓------------------------------------------------------------------
movego:
    # $t3 = $A1 IS THE LENGTH
    # precess of binary to decimal
    beq     $t0, $t3, strloop   # if $t0 = $t3(length of str) , go strloop
    mul     $v0, $v0, 2         # $v0 = 1 x 2 x 2 x 2....x 2
    addi    $t0, $t0, 1         # $t0 = $t0 + 1
    j       movego              # loop again

strloop:
    div     $v0,$v0,2           # $v0 = $v0 / 2
    bgt     $t1,$t4,printSum    # if $t1 > $t4 , go printsum
    lb      $s1, 0 ($a0)        # load new $a0 to $s0 
    sub     $s1,$s1,48          # $s1 = $s1 - 48 ( the ascii of "0" ) = to check is 1 or 0
    addi    $a0,$a0,1           # $a0 + 1 check the next char
    addi    $t1,$t1,1           # $t1 + 1 let > $t4
    mul     $v1,$v0,$s1         # $v1 = $s2 x $v1
    add     $s2,$s2,$v1         # $s2 = $s2 + $v1
    j       movego

printSum:
    move    $v1, $s2            # result put in $v1
    jr      $ra
.end str2int
#--------------------------------------------------------------------

# ----------
# procedure: print2
# $a2 = the integer to print
# return value: $v1 = $a2
# -----------
.globl print2
print2:
    la  $a0, ansBin     # print ansBin
    li  $v0, 4          # print String
    syscall

    la  $a0, newLine    # print newLine
    li  $v0, 4
    syscall

.end print2
# ----------
# procedure: print10
# $a2 = the integer to print
# return value: $v1 = $a2
# -----------
.globl print10
print10:
    la  $a0, ansDec             # print ansDec
    li  $v0, 4
    syscall

    addi    $a0,$t6,0           # print the answer of decimal number
    li  $v0, 1
    syscall

    la  $a0, newLine            # print newLine
    li  $v0, 4
    syscall
.end print10

# -----------
# procedure: print8
# $a2 = the integer to print
# return value: $v1 = $a2
# -----------
.globl print8

print8:
    # decimal --> octal
        li $s5, 10
        li $s3, 2
        div $t2,$a2,$s5
        mul $t2,$t2,$s3
        add $v1,$a2,$t2

exit_print8:
    la  $a0, ansOct             # print ansOct
    li  $v0, 4
    syscall

    addi    $a0,$v1,0           # print the answer of decimal number
    li  $v0, 1
    syscall

    la  $a0, newLine            # print newLine
    li  $v0, 4
    syscall

.end print8


# ----------
# procedure: print16
# $a2 = the integer to print
# return value: $v1 = $a2
# -----------
.globl print16
print16:
            la      $a0, ansHex             # print ansHex
            li      $v0, 4
            syscall

            add         $s0, $a2, $zero
            move        $a0, $s0        

            bne     $s0, $zero, non_zero

            addi    $a0, $s0, 48 # $a0 = 0, so print character ’0’

            li      $v0, 11      # call code to print character

            syscall

            j   exit_l

non_zero:   lui $t0,0xf000  # $t0 = 0xf0000000

            li  $t2,0       # $t2 = 0, think of the usage of $t2 below

            li  $t3,1       # $t3 = 1

            li  $t4,0       # $t4 = 0

loop:       beq $t4, 8, exit_l  # if $t4 > 8 go exit_l

            and $t1, $s0, $t0

            srl $t1, $t1, 28

            movn    $t2,$t3,$t1 # if($t1!=0) $t2=$t3 else do nothing

            beq $t2,$zero,shift

            bge $t1,10,letter   # 0<= $t1 < 10

            addi    $a0,$t1,48  # $a0 is equal to ‘0’~’9’

            j   print_char

letter:     addi    $a0,$t1,55  # 10 <= $t1 <=15, $a0 is equal to ’A’~’F’

print_char: li  $v0,11

            syscall

shift:      sll $s0,$s0,4

            addi    $t4,$t4,1

            j   loop    

exit_l:
            la  $a0, newLine            # print newLine
            li  $v0, 4
            syscall
.end print16

#----------------------------------
#数据段
.数据
msg:.ascii“信息:输入的32位无符号数字可以是前缀为\“b\,\n”的二进制数字
.ascii“\t\t\t或带前缀“0”的八进制,\n”
.ascii“\t\t\t或不带前缀的十进制\n”
.asciiz“\t\t\t或前缀为“0x\”的十六进制\n”
提示:.asciiz“\n输入一个数字:”
ansBin:.asciiz“将其转换为二进制:b”
ansDec:.asciiz“将其转换为十进制:”
ansOct:.asciiz“将其转换为八进制:0”
ansHex:.asciiz“将其转换为十六进制:0x”
公司:.asciiz“\n是否继续(y/n)?\n”
换行符:.asciiz“\n”
结束:.asciiz“\n结束\n”
缓冲区:。空间33
# ----------------------------------
#文本/代码段
.文本
格洛博梅因酒店
主要内容:
la$a0,味精#打印味精
李$v0,4
系统调用
打印提示:
la$a0,提示#打印提示
李$v0,4
系统调用
la$a0,缓冲区#这是输入$a0是全部,例如b10100
li$a1,33#a1的长度是33
li$v0,8#读取字符串
系统调用
磅$s0,0($a0)#$s0是第一个字符
#每个字符都有一个字节长
#现在$s0=第一个字符
bne$s0,98,notBin#98是ASCII码中的“b”
addi$a0,$a0,1#检查第二个字符(无b,0,0x)
#现在$s0=第二个字符
磅$s0,0($a0)
移动$s1,$s0
li$t5,2#二进制($a2=2)
endofnotBin:
#-----二进制到十进制------
jal str2int#go str2int,二进制到十进制
添加$t6、$v1、$0#保持打印10
移动$a2,$v1#$v1是十进制的ans
#八进制以$a2开头
日航印刷10
#结束
#--------------------------------------------------------
#----十进制到八进制---
日航印刷8
移动$a2,$v1
#结束
#----只需打印十进制-----
日航印刷10
移动$a2,$v1
#结束
#----十进制到十六进制-----
日航印刷16
#--------------------------------------------------------
#------结束----------------
打印组件:
la$a0,薪酬#打印薪酬
li$v0,4#打印字符串
系统调用
la$a0,缓冲区
li$a1,33#a1的长度为33
li$v0,8#读整数,写Y/N的地方
系统调用
磅$s0,0($a0)
beq$s0,89,打印提示#如果输入“Y”(89在ASCII中是Y),则转到打印提示
beq$s0,121,打印提示#如果输入“y”(121在ASCII中是y),则转到打印提示
beq$s0,78,结束#如果输入“N”(78在ASCII中为N),则结束
beq$s0,110,结束#如果输入“n”(110在ASCII中为n),则结束
最后:
la$a0,结束#打印结束
李$v0,4
系统调用
# -----
#完成,退出程序。
李$v0,10#呼叫退出代码
系统调用#系统调用
#--------------------------------------------------------------------
诺宾:待办事项
beq$s0,48,isOct#48是ASCII码中的“0”
beq$s0,49,isDex#49是ASCII码中的“1”
beq$s0,50,isDex#50是ASCII码中的“2”
beq$s0,51,isDex#51是ASCII码中的“3”
beq$s0,52,isDex#52是ASCII码中的“4”
beq$s0,53,isDex#53是ASCII码中的“5”
beq$s0,54,isDex#54是ASCII码中的“6”
beq$s0,55,isDex#55是ASCII码中的“7”
beq$s0,56,isDex#56是ASCII码中的“8”
beq$s0,57,isDex#57是ASCII码中的“9”
isOct:
addi$a1$a0,1
磅$s0,0($a1)
bne$S0120,isHex#120是ASCII码中的“x”
磅$s0,0($a0)
日航印刷2
j endofnotBin
isHex:
addi$a0,$a0,1#开始永久读取第三个代码
磅$s0,0($a0)#加载新的$s0
日航印刷2
j endofnotBin
#--------当前缀为十进制时--------
isDex:
#----十进制到二进制-----
日航印刷2
添加$t5、$0、$a0#复制一个用于八进制和十六进制
加上$t0,$零,$a0#$t0=$a0
添加$t1、$0、$0#$t1=0
加上$t3,$0,1#$t3=1
sll$t3,$t3,31#移动面具
addi$t4,$0,32#计算循环
第12条:
和$t1、$t0、$t3#以及带掩码的输入
beq$t1,$zero,print12#如果其值为0,则要打印的分支
加上$t1、$zero、$zero#零出$t1
addi$t1,$0,1#在$t1中放入1
j print12
打印12:
李$v0,1
移动$a0,$t1
系统调用
srl$t3、$t3、1
加上$t4,$t4,-1
bne$t4、$0、12
#----十进制到八进制-----
移动$a2,$t5
日航印刷8
移动$a2,$v1
#----十进制到十六进制-----
日航印刷16
j印刷公司
j endofnotBin
#--------当前缀为十进制时--------
.尾干管
# ----------
#程序:str2int
#$a0=输入字符串的起始地址,不包括前缀
#$a2=基数
#返回值=$v1
# -------------------------------------------------------------------------
.globl str2int
str2int:
磅$s0,0($a0)#因为第44行中有$a0+1
#$s0现在读取第二个字符(num)
#从第二端开始计算长度
移动$a1,$a0#$a1← $a0=($a0+1)
#----↓↓↓------------------------------------------------------------------
长度:
磅$s0,0($a1)#$s0=0+a1
#$s0=0+($a1+1)第二次
贝币$s0,10
.globl main: 

j one #when one is finished & receive the $ra ,continue the following execution
j two #same
j three #same

.end main

one:
   (codes)
   jr $ra 
#tell main that "one" is finished, go back to the main and continue to start "two"

two:
   (codes)
   jr $ra
#same

three:
   (codes)
   jr $ra
#same