Assembly

di il
8 risposte

Assembly

Utilizzando QtSpim, scrivere e provare un programma che permetta all’utente di selezionare una tra le seguenti opzioni:
a) richiede l’inserimento di un intero, visualizza a console se è un numero pari o dispari e ritorna al menù di scelta;
b) richiede l’inserimento di due interi, visualizza a console se la loro somma è un numero pari o dispari e ritorna al menù di scelta;
c) richiede l’inserimento di tre interi, ne visualizza su console il valore minimo e ritorna al menù di scelta;
d) visualizza un messaggio di uscita e termina il programma.


dopo aver fatto la prima opzione(a,b,c) si blocca
come mai ?
grazie mille


.data
asterischi: .asciiz "*******************************************\n"
menu2: .asciiz "** Scegliere una tra le seguenti opzioni **\n"
stacco: .asciiz "** **\n"
scelta_uno: .asciiz "** 1. controllo numero se è pari o dispari **\n"
scelta_due: .asciiz "** 2. Somma di 2 interi e controllo se è pari o dispari **\n"
scelta_tre: .asciiz "** 3. confronto tra 3 interi **\n"
scelta_quattro: .asciiz "** 4. Esci **"
inserisci: .asciiz "\n\n Inserisci il valore scelto: "
uno: .asciiz "\n Inserire un numero intero da controllare \n"
primo: .asciiz "\nPrimo: "
secondo: .asciiz "\nSecondo: "
terzo: .asciiz "\nTerzo:"
due: .asciiz "\n Inserire i due numeri da sommare\n"
tre: .asciiz "\n Inserire i tre numeri da confrontare \n"
minore: .asciiz "\n Il minore è : "
fine: .asciiz "\n Fine."
spazio: .asciiz "\n"
pari: .asciiz "\n il numero inserito è pari "
dispari: .asciiz "\n il numero inserito è dispari "
error: .asciiz "\nERRORE!!! L'intero inserito non rientra nel range possibile!"
.align 2
jump_table: .space 16 #dovendo memorizzare 4 indirizzi di 32 bit ciascuno, ho bisogno in totale di 16 byte
.text
.globl main

main:
#inizializzo la jump table
la $s1, jump_table #l'indirizzo di base della jump table viene copiato in $s1
la $t0, j_uno #carico l'indirizzo della prima opzione in $t0
sw $t0, 0($s1) #e lo memorizzo nell'area di memoria della jump table a partire dall'indirizzo di base
la $t0, j_due #faccio lo stesso per le altre opzioni con offset multipli di 4
sw $t0, 4($s1)
la $t0, j_tre
sw $t0, 8($s1)
la $t0, j_quattro
sw $t0, 12($s1)
#serie di istruzioni per stampare il menù
li $v0, 4
la $a0, asterischi
syscall

li $v0, 4
la $a0, menu2
syscall

li $v0, 4
la $a0, stacco
syscall

li $v0, 4
la $a0, scelta_uno
syscall

li $v0, 4
la $a0, scelta_due
syscall

li $v0, 4
la $a0, scelta_tre
syscall

li $v0, 4
la $a0, scelta_quattro
syscall

li $v0, 4
la $a0, asterischi
syscall

choose:
# stampa il messaggio che richiede l'inserimento
li $v0, 4
la $a0, inserisci
syscall

#legge la scelta
li $v0, 5
syscall

#è necessario controllare se il valore inserito rientri o meno nel range possibile
bgt $v0, 4, errore #se è maggiore di 4 c'è un errore
blt $v0, 1, errore #lo stesso se è minore di 1
#altrimenti calcoliamo l'indirizzo di salto
addi $v0, $v0, -1 #sottriamo un'unità dalla scelta perchè la memorizzazione degli indirizzi nella jump_table parte da zero
mul $v0, $v0, 4 #si moltiplica il valore ottenuto per quattro
add $t0, $v0, $s1 #si somma all'indirizzo a partire dal quale si trova la jump_table ottenendo l'area di memoria da cui
lw $t0, 0($t0) #si carica l'indirizzo della case action desiderata
jr $t0 #si salta all'indirizzo appena calcolato che corrisponde ad una delle quattro opzioni

errore:
li $v0, 4
la $a0, error
syscall

j choose

j_uno:
#stampa i messaggi relativi alla prima scelta
li $v0, 4
la $a0, uno
syscall

li $v0, 4
la $a0, primo
syscall

#legge il numero
li $v0, 5
syscall

move $t1, $v0 #salvo il valore in $t1
li $v0, 4

li $t3, 2

div $t1, $t3 # dividi il numero per 2
mfhi $t2 # Hi = HI contiene il resto e lo porto nel registro $t2
bne $t2, $zero, dispari
li $v0, 4
la $a0,pari
syscall
j choose


j_due:
#stampa i messaggi relativi alla seconda scelta
li $v0, 4
la $a0, due
syscall

li $v0, 4
la $a0, primo
syscall

#legge il primo intero da sommare
li $v0, 5
syscall

move $s1, $v0 #salvo il valore in $t1
li $v0, 4
la $a0, secondo
syscall

#legge il secondo intero da sommare
li $v0, 5
syscall

move $s2, $v0 #salvo il valore in $t2

add $s3, $s1, $s2 #eseguo la somma e metto il risultato in $t3

li $s4, 2
div $s3, $s4 # dividi il numero per 2
mfhi $s5 # Hi = HI contiene il resto e lo porto nel registro $t2
bne $s5, $zero,dispari
li $v0, 4
la $a0,pari
syscall

j choose


j_tre:
#stampa i messaggi relativi alla seconda scelta
li $v0, 4
la $a0, tre
syscall

li $v0, 4
la $a0, primo
syscall

#legge il primo intero
li $v0, 5
syscall

move $s2, $v0 #salvo il valore in $t1
li $v0, 4
la $a0, secondo
syscall

#legge il secondo intero
li $v0, 5
syscall

move $s3, $v0 #salvo il valore in $t2
li $v0, 4
la $a0, terzo
#legge il terzo intero
li $v0, 4
la $a0, terzo
syscall

li $v0, 5
syscall

move $s4, $v0 #salvo il valore in $t1

la $a0, minore
syscall

slt $s1,$s2,$s3
bne $s1, 1, second1
slt $s1,$s3,$s4
beq $s1, 1, stampa_s2
slt $s1,$s2,$s4
beq $s1, 1, stampa_s2
j stampa_s4

j choose

second1:
slt $s1, $s2, $s4
beq $s1,1, stampa_s3
slt $s1, $s3, $s4
beq $s1,1, stampa_s3
j stampa_s4

j choose

stampa_s4:

move $a0,$s4
li $v0,1
syscall

j choose

stampa_s3:
move $a0,$s3
li $v0,1
syscall

j choose

stampa_s2:
move $a0,$s2
li $v0,1
syscall

li $v0, 4
la $a0, spazio
syscall

j choose

j_quattro:
#stampa messaggio di chiusura
li $v0, 4
la $a0, fine
syscall

exit:
li $v0, 10 #exit
syscall

8 Risposte

  • Re: Assembly

    Chiarisci meglio cosa succede ... cosa vuol dire "si blocca"?
  • Re: Assembly

    Dopo aver eseguito una delle 3 opzioni " a,d,c " dovebbre ritornare al menu invece, da un errore e si blocca..
  • Re: Assembly

    A me no, eseguo il primo e alla fine torna ... ma quale errore specifico hai?
  • Re: Assembly

    Sulla 3 opzione mi da un unsignaled address... sai perchè ?
  • Re: Assembly

    Succede perché modifichi $s1 che è usato come indirizzo di base della jump table.
    Devi reimpostare $s1 subito dopo l'etichetta choose ... ovveo
    
    choose:
    la $s1, jump_table 
    # stampa il messaggio che richiede l'inserimento
    li $v0, 4
    la $a0, inserisci
    syscall
    
  • Re: Assembly

    Grazie mille!
    ti posso chiedere un ultimo favore ?

    scrivere e provare un programma che legga due interi non negativi x e y e visualizzi su console il loro prodotto prod(x,y) implementando le seguenti due funzioni ricorsive:

    prod : se y = 0 ritona 0
    se y > 0 richima sum ( x , prod (x, y-1) )

    sum : se y =0 ritorna x
    se y > 0 1+sum(x, y-1)

    mi da qualche errorino


    #Es_2 (procedura sum)
    .data
    risultato: .asciiz "\nIl risultato è "
    inserisci1: .asciiz "\n Inserire il primo numero numero x : "
    inserisci2: .asciiz "\n Inserire il secondo numero numero y : "
    .text
    .globl main

    prod:
    sub $sp, $sp, 12 #si crea l'area di memoria per la procedura
    sw $a0, 4($sp) #essendo ricorsiva, memorizza l'intero passato come argomento
    sw $a1, 4($sp) #essendo ricorsiva, memorizza l'intero passato come argomento
    sw $a2, 4($sp)
    sw $ra, 0($sp) #essendo ricorsiva, salvo il registro di ritorno $ra nella pila
    beq $a1, $zero, zero #se l'intero è zero devo ritornare questo valore
    jal sum
    jal prod
    addi $sp, $sp, 12 #ripristino dello stack
    jr $ra

    sum:
    beq $a1, $zero, x
    sub $a1,$a1,1
    beq $a1, $zero, xpiù1 ------------------- mi dice che zero non è riconosciuta
    addi $a2, $a0, $a1 -------------------errore sintattico
    li $v0,$a2
    jr $ra

    xpiù1:
    lw $ra, 0($sp) #prima di tutto recupero l'indirizzo di ritorno e lo carico in $ra
    addi $sp, $sp, 12 #ripristino lo stack sommando il numero di byte che gli avevo sottratto all'inizio della procedura
    addi $a0,$a0,1
    li $v0, $a0 #ritorno il valore di x
    jr $ra #torno al chiamante

    x:
    lw $ra, 0($sp) #prima di tutto recupero l'indirizzo di ritorno e lo carico in $ra
    addi $sp, $sp, 12 #ripristino lo stack sommando il numero di byte che gli avevo sottratto all'inizio della procedura
    li $v0, $a0 #ritorno il valore di x
    jr $ra #torno al chiamante


    zero: #oltre a ritornare il valore zero devo anche ripristinare lo stack

    lw $ra, 0($sp) #prima di tutto recupero l'indirizzo di ritorno e lo carico in $ra
    addi $sp, $sp, 12 #ripristino lo stack sommando il numero di byte che gli avevo sottratto all'inizio della procedura
    li $v0, 0 #ritorno il valore zero
    jr $ra #torno al chiamante
    uno:
    #anche in questo caso valgono le considerazioni fatte precedentemente
    lw $ra, 0($sp)
    addi $sp, $sp, 12
    li $v0, 1
    jr $ra
    due:
    #anche in questo caso
    lw $ra, 0($sp)
    addi $sp, $sp, 12
    li $v0, 2
    jr $ra

    ############################## procedura main

    main:
    li $v0, 4
    la $a0, inserisci1
    syscall

    #si legge l'intero scelto dall'utente
    li $v0, 5
    syscall

    move $a0, $v0 #l'intero scelto si passa come parametro alla procedura
    jal prod

    li $v0, 4
    la $a0, inserisci2
    syscall

    move $zero,$a2
    #si legge l'intero scelto dall'utente
    li $v0, 5
    syscall

    move $a1, $v0 #l'intero scelto si passa come parametro alla procedura
    jal prod
    move $t0, $v0 #si copia il valore in $t0 perchè $v0 deve essere usato per la syscall


    li $v0, 4
    la $a0, risultato
    syscall


    #si stampa il valore copiandolo da $t0 in $a0
    li $v0, 1
    move $a0, $t0
    syscall

    #uscita dal programma
    li $v0 10
    syscall
  • Re: Assembly

    Mi da un syntax error addi $a2, $a0,$a1 non riesco a capire perchè...
  • Re: Assembly

    Migliorato ma ancora non ci sono, mi da bad address e aritmethic overflow
    #Es_2 (procedura sum)
    .data
    risultato: .asciiz "\nIl risultato è "
    inserisci1: .asciiz "\n Inserire il primo numero numero x : "
    inserisci2: .asciiz "\n Inserire il secondo numero numero y : "
    .text
    .globl main

    prod:
    sub $sp, $sp,-16 #si crea l'area di memoria per la procedura
    sw $a0, 4($sp) #essendo ricorsiva, memorizza l'intero passato come argomento
    sw $a1, 4($sp) #essendo ricorsiva, memorizza l'intero passato come argomento
    sw $ra, 0($sp) #essendo ricorsiva, salvo il registro di ritorno $ra nella pila
    beq $a1, $zero, zero #se l'intero è zero devo ritornare questo valore
    jal sum
    lw $a0, 0($sp)
    lw $a1, 0($sp)
    jal prod
    addi $sp, $sp, 12 #ripristino dello stack
    jr $ra

    sum:
    beq $a1,$zero, x
    sub $a1,$a1,1
    beq $a1, $zero, x1
    add $a0, $a0, $a1
    move $v0,$a0
    jr $ra

    x1:
    lw $ra, 0($sp) #prima di tutto recupero l'indirizzo di ritorno e lo carico in $ra
    addi $sp, $sp, 12 #ripristino lo stack sommando il numero di byte che gli avevo sottratto all'inizio della procedura
    addi $a0,$a0,1
    move $v0, $a0 #ritorno il valore di x
    jr $ra #torno al chiamante

    x:
    lw $ra, 0($sp) #prima di tutto recupero l'indirizzo di ritorno e lo carico in $ra
    addi $sp, $sp, 12 #ripristino lo stack sommando il numero di byte che gli avevo sottratto all'inizio della procedura
    move $v0, $a0 #ritorno il valore di x
    jr $ra #torno al chiamante


    zero: #oltre a ritornare il valore zero devo anche ripristinare lo stack

    lw $ra, 0($sp) #prima di tutto recupero l'indirizzo di ritorno e lo carico in $ra
    addi $sp, $sp, 12 #ripristino lo stack sommando il numero di byte che gli avevo sottratto all'inizio della procedura
    li $v0, 0 #ritorno il valore zero
    jr $ra #torno al chiamante

    ############################## procedura main

    main:
    li $v0, 4
    la $a0, inserisci1
    syscall

    #si legge l'intero scelto dall'utente
    li $v0, 5
    syscall

    move $a0, $v0 #l'intero scelto si passa come parametro alla procedura

    li $v0, 4
    la $a0, inserisci2
    syscall


    #si legge l'intero scelto dall'utente
    li $v0, 5
    syscall

    move $a1, $v0 #l'intero scelto si passa come parametro alla procedura
    jal prod

    move $t0, $v0 #si copia il valore in $t0 perchè $v0 deve essere usato per la syscall


    li $v0, 4
    la $a0, risultato
    syscall


    #si stampa il valore copiandolo da $t0 in $a0
    li $v0, 1
    move $a0, $t0
    syscall

    #uscita dal programma
    li $v0 10
    syscall
Devi accedere o registrarti per scrivere nel forum
8 risposte