Esercizio MIPS

di il
8 risposte

Esercizio MIPS

Questa soluzione è puramente a scopo didattico dato che ce ne sarebbero altre molto meno ridondanti.
Il programma legge interi da tastiera e smette quando gli si da in pasto 0, per poi scrivere su console i numeri in posizione pari e la loro somma.
Se non inizializzo nessun vettore con ad esempio vettore: .word 0:100, inserendo i valori mi sovrascrive la stringa LA SOMMA E'. Invertendo la loro posizione nel segmento .data mi da errore.
Consigli in merito?


.data

vettore: .word
stringa: .asciiz "LA SOMMA E'"

.text
	addi $t2, $zero, 0 #INIZIALIZZO INDICE VETTORE
	
lettura:
	li $v0, 5	#LEGGO UN INTERO DA TASTIERA
	syscall
	move $t1, $v0
	
	beq $t1, $zero, stop
	
	sw $t1, vettore($t2)
	addi $t2, $t2, 4
	
	j lettura
	
stop:
	addi $t0, $zero, 0
	addi $t5, $zero, 0

stampa:

	bge $t0, $t2, fine
	
	lw $t1, vettore($t0)
	add $t5, $t5, $t1
	addi $t0, $t0, 8
	
	
	li $v0, 1
	move $a0, $t1
	syscall
	
	li $v0, 11
	li $a0,  32
	syscall
	
	j stampa

fine:
	
	li $v0, 4
	la $a0, stringa
	syscall
	
	li $v0, 10
	syscall

8 Risposte

  • Re: Esercizio MIPS

    Un'altra cosa: c'è un modo per gestire l'eccezione nel caso in cui appena il programma richiede di inserire l'intero da tastiera si preme direttamente INVIO?
  • Re: Esercizio MIPS

    Ciao
    allora nella tua routine manca l'entry point
    in assembler mips l'entry point e costituito dalle seguenti righe:
    
    .globl main
    main:
    queste due istruzioni vanno poste subito dopo la
    .text
    servono a far capire al computer dove realmente inizia il programma.

    Paolovox ha scritto:


    Se non inizializzo nessun vettore con ad esempio vettore: .word 0:100, inserendo i valori mi sovrascrive la stringa LA SOMMA E'.
    non dipende dall'inizializzazione o meno del vettore dipende dal fatto che non specifichi quanto deve essere grande il vettore.
    quindi la sintassi corretta è
    vettore: .word numero elementi

    Paolovox ha scritto:


    Un'altra cosa: c'è un modo per gestire l'eccezione nel caso in cui appena il programma richiede di inserire l'intero da tastiera si preme direttamente INVIO?
    pultroppo no perchè hanno scritto la syscall con questa caratteristica.
    in aggiunta alla tua procedura manca la stampa del risultato.
      # stampa risultato
       li $v0,1
       move $a0,$t5
       syscall
    adesso se ti vuoi leggermente complicare le cose (facendo un pò di esercizio) adatta il programma a fare la stessa cosa per i numeri dispari.
    spero di esserti stato d'aiuto
    saluti smalldragon
  • Re: Esercizio MIPS

    Quindi come entry point avrei potuto anche scegliere la label lettura?
    Pure assegnando una dimensione di 0:20 al vettore è possibile sconfinare da tale intervallo. I controlli vanno fatti durante il ciclo di inserimento e lettura per evitare un BoF?
    Ti ringrazio sei stato molto chiaro.
    Vabbè per leggere i dispari comincio a leggere dal primo indirizzo del vettore+4, e facendo salti di 8.
  • Re: Esercizio MIPS

    Ciao
    si come entry point puoi usare la label che vuoi basta che sia uguale alla quella che indichi in .globl

    Paolovox ha scritto:


    Pure assegnando una dimensione di 0:20 al vettore è possibile sconfinare da tale intervallo. I controlli vanno fatti durante il ciclo di inserimento e lettura per evitare un BoF?
    naturalmente

    Paolovox ha scritto:


    Vabbè per leggere i dispari comincio a leggere dal primo indirizzo del vettore+4, e facendo salti di 8
    no!
    inquanto in assembler cosi come in c i vettori iniziano da 0 e non da 1
    e siccome lo 0 viene considerato pari il primo record deve essere scartato
    fatto ciò puoi proseguire come sai.
    comunque scrivi il codice e poi ne parliamo
    saluti smalldragon
  • Re: Esercizio MIPS

    L'ho già fatto modificanto un solo valore, ovvero da dove parte la lettura del vettore per il controllo degli indici dispari.
    
    .data
    
    
    vettore: .word 0
    stringa: .asciiz "LA SOMMA E':"
    
    .text
    	addi $t2, $zero, 0 #INIZIALIZZO INDICE VETTORE
    	
    lettura:
    	li $v0, 5	#LEGGO UN INTERO DA TASTIERA
    	syscall
    	move $t1, $v0
    	
    	beq $t1, $zero, stop
    	
    	sw $t1, vettore($t2)
    	addi $t2, $t2, 4
    	
    	j lettura
    	
    stop:
    	addi $t0, $zero, 4 #<------------- anzichè 0
    	addi $t5, $zero, 0
    
    stampa:
    
    	bge $t0, $t2, fine
    	
    	lw $t1, vettore($t0)
    	add $t5, $t5, $t1
    	addi $t0, $t0, 8
    	
    	
    	li $v0, 1
    	move $a0, $t1
    	syscall
    	
    	li $v0, 11
    	li $a0,  32
    	syscall
    	
    	j stampa
    
    fine:
    	
    	li $v0, 4
    	la $a0, stringa
    	syscall
    	
    	li $v0, 11
    	li $a0,  32
    	syscall
    	
    	li $v0, 1
    	move $a0, $t5
    	syscall
    	
    	li $v0, 10
    	syscall
    
    
  • Re: Esercizio MIPS

    Allora
    vedo che ancora non hai digerito la questione del entry point.
    addi $t2, $zero, 0 #INIZIALIZZO INDICE VETTORE
    questa istruzione deve stare sotto la main e non può stare libera nel segmento dati.
    mentre la
    .globl main
    è facoltativa
    la label main: non lo è
    il motivo è:
    che il compilatore oltre a generare il tuo codice che giustamente del main se ne frega
    genera anche l'assegnazione interna dei segmenti e quando ha finito ritorna alla main
    per eseguire il tuo codice.
    l'assegnazione dei segmenti avviene tra le istruzioni
    .text
    main:
    ergo la main: la devi inserire per forza!
    poi se nella dichiarazione del vettore metti uno 0 nella dimensione la seconda variabile viene sovrascritta quindi assegnagli un valore che reputi congruo.
    per il resto va bene.
    adesso se ti va di far pratica
    ti propongo un esercizio leggermente più difficile
    scambia i pari con i dispari se la differenza tra i due numeri da scambiare e > 0
    come output devi stampare il numero di scambi e la differenza di ogni scambio.
  • Re: Esercizio MIPS

    Wow bell'evoluzione del problema. Appena ho un pò di tempo ti posto la mia soluzione magari in maniera più ragionata. Ti ringrazio davvero tanto
  • Re: Esercizio MIPS

    In pratica dalla traccia ne ho dedotto che il nuovo scopo fosse quello di ordinare il vettore in ordine crescente.
    
    .globl main
    .data
    
    vettore: .word 0:100
    stringa: .asciiz "IL VETTORE ORDINATO E': "
    Nswitch: .asciiz "IL NUMERO DI SCAMBI EFFETTUATI E': "
    
    .text
    main:
    	move $t0, $zero #inizializzo indice vettore
    	li $s0, 0
    	
    lettura:
    	li $v0, 5
    	syscall
    	move $t1, $v0	#leggo intero da tastiera
    	
    	beq $t1,$zero, precontrollo
    	sw $t1, vettore($t0)
    	addi $t0, $t0, 4
    
    	j lettura
    	
    precontrollo:
    	li $s1, 0
    	subi $s4, $t0, 4
    	li $t4, 0 #indice dei pari
    	li $t5, 4 #indice dei dispari
    controllo:
    	
    	
    	bgt $t5, $s4, prestampa #se l'indice dei dispari è maggiore della dimensione del vettore esco
    	lw $t6, vettore($t4)
    	lw $t7, vettore($t5)
    	sub $t8, $t6, $t7 #metto la sottrazione tra elemento pari ed elemento dispari
    	bgtz $t8, switch
    	addi $t4,$t4,4
    	addi $t5,$t5,4
    	j controllo
    	
    switch:	
    	li $s1, 1
    	sw $t6, vettore($t5)
    	sw $t7, vettore($t4)
    	addi $t4,$t4,4
    	addi $t5,$t5,4
    	addi $s0, $s0, 1
    	
    	j controllo
    	
    prestampa:
    	bnez $s1, precontrollo
    	addi $t3, $t3, 0
    	
    	li $v0, 4
    	la $a0, stringa
    	syscall
    stampa:
    	
    	li $v0,1
    	lw $a0, vettore($t3)
    	syscall
    	
    	li $v0, 11
    	li $a0, 32
    	syscall
    	
    	beq $t3, $s4, fine
    	
    	addi $t3, $t3, 4
    	j stampa
    fine:	
    	li $v0, 11
    	li $a0, 13 #carriage return
    	syscall 
    	
    	li $v0, 4
    	la $a0, Nswitch
    	syscall
    	
    	li $v0,1
    	move $a0, $s0
    	syscall
    	
    	li $v0, 10
    	syscall
    
    
    
    Perchè non mi funziona il carriage return?
Devi accedere o registrarti per scrivere nel forum
8 risposte