2010-05-29 5 views
1

Je me demandais, est-il un moyen de MIPS pour stocker une sommation des nombres comme une chaîne et lire plus tard les octet par octet, par exemple:Enregistrement des entiers comme des chaînes dans MIPS

la somme 657 -> sw dans une directive .ascii -> plus tard lb sur le premier index pour obtenir 6 (en code ASCII) même avec 5 et ainsi de suite. Est-ce possible?

+0

connexes: l'algorithme générique en C (division répétée par 10, dernier chiffre = reste). La réponse ici fonctionne à partir de la fin d'un tampon, car l'algorithme produit des chiffres dans l'ordre inverse. –

Répondre

2

Bien sûr. La directive « .ascii » est pas, mais une directive .byte axée sur le stockage du texte ASCII

 
    .ascii "PP" 

est comme

 
    .byte 80,80 

Vous pouvez utiliser .space pour faire de la place pour votre chaîne ASCII, puis utiliser le tampon dans la conversion d'entier en ASCII, si vous voulez dire ceci par "sw dans la directive .ascii" de entier. Le code suivant convertit le "nombre binaire" en une chaîne ASCII en utilisant itoa et l'imprime (juste pour tester) avec print_string. La fonction utilise un tampon et renvoie le pointeur au premier chiffre ASCII utilisable pour l'impression. Cela pourrait être utilisé comme une première fonction d'assistance pour une implémentation de la fonction sprintf.


     .data 

buffer: 
     .space 32 


     .text 
     # the main supposes env. like spim or MARS 
main: 
     li $a0, 1234  # a number 
     jal itoa 
     move $a0, $v0 
     li $v0, 4   # print_string  
     syscall 
     li $v0, 10 
     syscall    # exit 

itoa: 
     la $t0, buffer # load buf 
     add $t0, $t0, 30 # seek the end 
     sb $0, 1($t0)  # null-terminated str 
     li $t1, '0' 
     sb $t1, ($t0)  # init. with ascii 0 
     slt $t2, $a0, $0 # keep the sign 
     li $t3, 10  # preload 10 
     beq $a0, $0, iend # end if 0 
     neg $a0, $a0 
loop: 
     div $a0, $t3  # a /= 10 
     mflo $a0 
     mfhi $t4   # get remainder 
     add $t4, $t4, $t1 # convert to ASCII digit 
     sb $t4, ($t0)  # store it 
     sub $t0, $t0, 1 # dec. buf ptr 
     bne $a0, $0, loop # if not zero, loop 
     addi $t0, $t0, 1 # adjust buf ptr 
iend: 
     beq $t2, $0, nolz # was < 0? 
     addi $t0, $t0, -1 
     li $t1, '-' 
     sb $t1, ($t0) 
nolz: 
     move $v0, $t0  # return the addr. 
     jr $ra   # of the string 

Une fois que vous avez v0 $ dans la principale, lb R, ($v0) choix "1", lb R, 1($v0) choix de deuxième chiffre (2) et ainsi de suite; rappelez-vous que la chaîne est terminée par zéro, donc si vous choisissez 0 (numérique), vous devez vous arrêter

+1

C'est un peu maladroit dans quelques endroits. Vous n'avez pas besoin de garder «0» dans un registre, vous pouvez ajouter addui $ t4, $ t4, «0». ("0" est une petite constante qui fonctionne comme un immédiat). Aussi, 'la $ t0, buffer + 30' devrait fonctionner. Il n'est pas nécessaire de charger la mauvaise adresse immédiatement, puis de l'ajouter au moment de l'exécution. –

+1

A part ça, c'est sympa (et gérer des entiers signés est un bon bonus). Travailler en arrière à partir de la fin d'un tampon est certainement la meilleure approche (vs pousser les chiffres sur la pile ou les imprimer un à la fois.) –

Questions connexes