2013-04-11 164 views
1

我正在編寫一些MIPS代碼來獲取一串ASCII數字並將該字符串轉換爲一個整數。該字符串由用戶輸入並且最多可以爲10位數字。我的代碼工作正常,並使用顯式的方法來執行循環加法後,乘以10的冪的最小有效數字的字符串由數組索引確定,從最後輸入的數字(10^0)開始到第一個數字輸入(10^n,n =數組中的位數)。在MIPS /彙編程序中將ASCII數字的字符串轉換爲int

我想知道是否有更快或更短的替代方法來編寫。特別是,我想知道如果使用邏輯位移可能會縮短此過程。任何想法優化或改善這個代碼將不勝感激!另外,作爲一個附註,我想使用jal調用gets和readInt子例程,但是因爲gets和readInt都調用子例程,所以在main方法中使用jal來調用gets或readInt會導致問題。任何想法如何解決這個問題?再次感謝 乾杯

PS:對不起,這個代碼中的註釋的格式,複製和MARS模擬器入堆棧溢出文本框中粘貼引起對準被關閉:/

#IO 
#Prompts user to input 10 ascii digits into an array 
#Converts the string of digits into a single int 
#Also handles any number of digits between 1 and 10 
#Returns 0 if non-digit chars are entered into the string 

.data   #declaration of vars follows 
array: .space 11 #reserves space for a 10 elem array 
char: .space 2 
prompt: .asciiz "Please enter 10 numbers, then press ENTER: \n" 
null: .asciiz "" 
space: .ascii " " 
newline: .asciiz "\n" 
.text   #instructions follow 

main: 
la $a0, prompt  #load prompt message into $a0 for syscall 
li $v0, 4    #load syscall to print string 
syscall   #print prompt message 
j readInt    #call readInt function to get user input string   

gets:   #read multiple chars from keyboard buffer until ENTER key, 
          #add NULL char and store into buffer pointed to by *array 
          #passed to the subroutine 
la $s1, array  #set base address of array to s1 
loop:   #start of read loop 
jal getc  #jump to getc subroutine 
lb $t0, char  #load the char from char buffer into t0, stripping null 
sb $t0, 0($s1)  #store the char into the nth elem of array 
lb $t1, newline  #load newline char into t1 
beq $t0, $t1, done #end of string? jump to done 
addi $s1, $s1, 1 #increments base address of array 
j loop   #jump to start of read loop 

getc:   #read char from keyboard buffer and return ascii value 
li $v0, 8  #call code for read string 
la $a0, char  #load address of char for read 
li $a1, 2  #length of string is 1byte char and 1byte for null 
syscall   #store the char byte from input buffer into char 
jr $ra   #jump-register to calling function 

readInt:  #read string of ascii digits, store into a local variable and 
        #convert into integer, return that int unless string contains 
        #non-integers 
j gets   #let s1 be top address of array, let s0 be the digitcounter 
done:   #let s2 be the sum total 
addi $s1, $s1, -1 #reposition array pointer to last char before newline char 
la $s0, array  #set base address of array to s0 for use as counter 
addi $s0, $s0, -1 #reposition base array to read leftmost char in string 
add $s2, $zero, $zero #initialize sum to 0 
li $t0, 10  #set t0 to be 10, used for decimal conversion 
li $t3, 1 
lb $t1, 0($s1)  #load char from array into t1 
blt $t1, 48, error #check if char is not a digit (ascii<'0') 
bgt $t1, 57, error #check if char is not a digit (ascii>'9') 
addi $t1, $t1, -48 #converts t1's ascii value to dec value 
add $s2, $s2, $t1 #add dec value of t1 to sumtotal 
addi $s1, $s1, -1 #decrement array address 
lp:   #loop for all digits preceeding the LSB 
mul $t3, $t3, $t0 #multiply power by 10 
beq $s1, $s0, FIN #exit if beginning of string is reached 
lb $t1, ($s1)  #load char from array into t1 
blt $t1, 48, error #check if char is not a digit (ascii<'0') 
bgt $t1, 57, error #check if char is not a digit (ascii>'9') 
addi $t1, $t1, -48 #converts t1's ascii value to dec value 
mul $t1, $t1, $t3 #t1*10^(counter) 
add $s2, $s2, $t1 #sumtotal=sumtotal+t1 
addi $s1, $s1, -1 #decrement array address 
j lp   #jump to start of loop 

error:   #if non digit chars are entered, readInt returns 0 
add $s2, $zero, $zero 
j FIN 

FIN: 
li $v0, 1 
add $a0, $s2, $zero 
syscall 
li $v0, 10  #ends program 
syscall 

回答

2

假設條件$s1指向一個NULL結尾的字符串(即,以最顯著位)的開始,$t0包含10時,和$s2包含0:

lp:   
    lbu $t1, ($s1)  #load unsigned char from array into t1 
    beq $t1, $0, FIN  #NULL terminator found 
    blt $t1, 48, error #check if char is not a digit (ascii<'0') 
    bgt $t1, 57, error #check if char is not a digit (ascii>'9') 
    addi $t1, $t1, -48 #converts t1's ascii value to dec value 
    mul $s2, $s2, $t0 #sum *= 10 
    add $s2, $s2, $t1 #sum += array[s1]-'0' 
    addi $s1, $s1, 1  #increment array address 
    j lp     #jump to start of loop 

這具有一個每次迭代少,並且在進入循環之前不需要知道字符串的長度。

4

通過安定與0x0F這樣掩蔽的前四個位串下面

andi $t0,$t0,0x0F # where $t0 contains the ascii digit . 

現在$t0具有它的INT。