Imprimarea caracterului x într-un șir de caractere (MIPS) (Programare, Asamblare, Mips, Qtspim)

Trojax a intrebat.

Programul meu ar trebui să facă următoarele:-obținerea continuă a unui număr întreg de la utilizator (x),-imprimarea caracterului de la poziția x în șirul de caractere.-Programul iese atunci când utilizatorul introduce 0.

.text           
.globl __start  
__start:
    li $s3,20 #string length

start:      li $v0,5 
    syscall
    move $s0,$a0 #integer now in $a0
    beq $s0,$zero,exit

    li $s1,0 #counter is 0
    la $s2,str #address of string now is $s2

loop:lbu $t1,0($s2) #choosing char of string
    addi $s1,1 #increment counter by 1
    addi $s2,1 #next char
    beq $s1,$s0,print  #is the char at the position we entered?
    j loop

print:      lbu $a0,0($t1) #<------------#
    li $v0,11
    syscall
    j start

exit:       li $v0,10
    syscall     



.data
str: .asciiz "abcdefghijklmnopqrst"

Continui să primesc: „Exception occured at PC=0x00400034” și „Bad address in data stack read: 0x…” exact când încerc să execut linia pe care am marcat-o.

2 răspunsuri
Michael

$t1 nu conține o adresă validă în punctul în care faci lbu $a0,0($t1). Ceea ce ai în $t1 acolo este ultimul caracter citit din șirul de caractere înainte de a ieși din loop bucla.

Chiar nu înțeleg care este rostul buclei. Spuneți că aveți un șir de caractere și un număr întreg X și că doriți să imprimați caracterul de la offsetul X din șir. Deci, citiți doar acel caracter și ați terminat:

la $a1,string
addu $a1,$a1,$s0   # $a1 = &str[x].  assumes x is in $s0
lbu $a0,($a1)      # read the character
li $v0,11
syscall            # and print it

Comentarii

  • Deși acest lucru pare corect, se tipărește întotdeauna caracterul ‘b’, indiferent ce scriu.În metoda mea (știu că nu este cea mai eficientă) vreau să mut acel caracter la $a0, astfel încât să nu poată fi tipărit.Am încercat să folosesc atât sb cât și lbu, dar niciuna dintre ele nu pare să funcționeze. –  > Por Trojax.
  • Ei bine, muți valoarea greșită în $s0. syscall 5 returnează numărul întreg citit în $v0, , nu $a0. –  > Por Michael.
  • Mulțumesc mult!Asta explică totul. –  > Por Trojax.
user11334153
.data
String: .space 1000
StringSize: .word  250
Msg: .asciiz "String length is: "

.text       
.globl main 
main:   
lw $a1, StringSize
la $a0, String                    # a0 points to the string
li $v0, 8
syscall

add $t2, $a0, $zero               # t2 points to the string
add $t1, $zero, $zero             # t1 holds the count
addi $t3, $zero, 10

LoopString: lb $t0, 0($t2)        # get a byte from string
beq $t0, $zero,  EndLoopString    # zero means end of string
beq $t0, $t3, Pointer             # remove newline (linefeed)
addi $t1,$t1, 1                   # increment count

Pointer:    addi $t2,$t2, 1       # move pointer one character
        j LoopString              # go round the loop again
EndLoopString:

la $a0, Msg                       # system call to print
add, $v0, $zero, 4                # out a message
syscall

add $a0, $t1, $zero               # system call to print
add, $v0, $zero, 1                # out the length worked out
syscall     

add, $v0, $zero, 10
syscall                           # good byeee :) ...