[Assembly-MIPS] moltiplicare 2 numeri grandi

di il
1 risposte

[Assembly-MIPS] moltiplicare 2 numeri grandi

Buongiorno,

sto scrivendo un programma che calcoli il prodotto scalare di 2 vettori. Di questi vettori, uno ha i valori messi in memoria(dimensione 10), l'altro si crea in maniera incrementale con un ciclo(restituendo 10 elementi che sono--->1,2,3,4,5,6,7,8,9,10). Ora il programma funziona se le componenti in memoria del vettore sono numeri bassi, a se per caso stabilisco di dover lavorare con numeri(decimali) alti ad esempio 1000000000 2000000000 300000000 400000000 ecc ecc allora esce tutto sbagliato. Fondamentalmente immagino che il PBL sia dato dall'overflow della "mul" che ha bisogno di porre il risultato in 64 bit. So che ci sono le "mflo" e "mfhi" che consentono di recuperare i valori di questi 2 registri speciali. Ma non so come elaborare una routine che gestisca l'overflow e che mi consenta di stampare poi un prodotto scalare che sarà piuttosto grande come numero...qualcuno riesce a darmi un suggerimento?
grazie!
posto la parte di codice omettendo parti che non riguardano il problema che ho(routine di stampa e creazione vettore 1)

prodotto_v:
		lw $t7, vettore($s1)		#carico il primo elemento del vettore 1
		lw $t6, vettore2($s3)		#carico il primo elemento del  vettore 2
		mul $t5, $t6, $t7		#moltiplico...
		addi $s1, $s1, 4		#incremento indice indirizzamento
		addi $s3, $s3, 4		#incremento indice indirizzamento
		addi $t9, $t9, -1		#decr. contatore d'appoggio
		sw $t5, prodotto($s7)		#scrivo il risultato nella prima casella del vettore scalare risultato
		addi $s7, $s7, 4		#incremento indice indirizzam. vettore risultato
		bgt $t9, $zero,prodotto_v	#finchè t9 > 0 ripeto tutto 

		jal stampa_prodotto
		
		la $a0, spazio2
		li $v0, 4
		syscall
		
		li $s7, 0			#azzero indice indirizzamento
		li $t0, 0			#registro d'appoggio
		li $t1, 0			#registro che conterrà il prodotto scalare
		li $t2, 10			#contatore d'appoggio

prod_scalare:	
                lw $t0, prodotto($s7)		#carico primo elemento del vettore dei prodotti
		add $t1, $t1, $t0		#t1 conterra' il valore del prodotto scalare----> sommo in maniera incrementale
		sub $t2, $t2, 1			#decremento il contatore t2
		addi $s7, $s7, 4		#elemento successivo vettore prodotto
		bgtz $t2, prod_scalare		#se il contatore d'appoggio è maggiore di zero somma l'elemento successivo
		move $a0, $t1			#se gli elementi sono finiti, stampa il prodotto scalare
		li $v0, 1
		syscall
		
		j esci

1 Risposte

  • Re: [Assembly-MIPS] moltiplicare 2 numeri grandi

    Ciao
    per gestire un overflow in Mips non esiste una istruzione ben specifica in quanto le istruzioni di moltiplicazione sia esse a 16-32 o 64 bit ignorano il segnale lasciandolo gestire direttamente al sistema operativo.
    però c'è una soluzione.
    quando avviene una moltiplicazione a 32 bit e si verifica un overflow succede che la parte alta hi viene impostata a zero.
    o la parte fa raddoppiare il segno nella parte bassa del numero.
    cio dipende da quale istruzione usi per fare la moltiplicazione se usi una multu allora la parte alta in caso di overflow sara posta a 0.
    mentre per la mult vale il raddoppio del segno in caso di overflow.
    cosi se tu usi la multu basta che copi la parte alta (hi) tramite l'istruzione mfhi e poi ne verifichi il valore con 0.
    mentre se tu usi una istruzione mult dovrai verificare che il segno non sia ripetuto nella parte bassa ed in questo caso dovrai usare l'istruzione mflo che funziona esattamente come la mfhi ma per la parte bassa.
    la sintassi di mfhi è mfhi registro destinazione
    la sintassi di mflo è mflo registro destinazione
    io ti consiglio di usare la mfhi e più intuitiva.
    spero di esserti stato d'aiuto
    se non hai capito qualcosa fammelo sapere.
Devi accedere o registrarti per scrivere nel forum
1 risposte