Mips 如何将jr$ra直接放置到正确的位置?
我想跳到打印组件,但现在我写了这段代码,它显示了 尝试在0x00400324执行非指令 在QTspim中。我希望我能学会如何放置它 另外,我不能跳转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
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