Vai al contenuto
PLC Forum


moltiplicazione in assembler


ziopolly

Messaggi consigliati

Buongiorno,

Ho un registro che contiene il numero di decine (max 9) ed un secondo registro che contiene le unità (max 9).

Come posso convertire le due cifre in un unico numero?

Premetto che l'unico linguaggio che conosco (si fa per dire) è l'assembler.

Grazie per l'attenzione

Link al commento
Condividi su altri siti


La soluzione che ho elaborato mi sembra poco razionale.

Quale altra soluzione conoscete?

movfw Decine

movwf Conta

btfsc Conta,0 ;Conta=0?

call Moltiplica ;NO

;SI

movfw Unita

addwf Somma

Moltiplica

movlw 10

addwf Somma

decfsz Conta ;Conta-1=0?

goto Moltiplica ;NO

return ;SI

Link al commento
Condividi su altri siti

Moltiplichi per dieci le decine e le sommi alle unità

Se non sai come eseguire la moltiplicazione ti indico la via più semplice, anche se on è universale e non è molto efficiente.

Sommi a se stesso il numero per cinque volte A= A + A + A + A + A;

poi esegui uno shift a sinistra di un passo. Le 5 somme equivalgono ad una moltiplicazione per 5, mentre lo shift a sx equivale ad una moltiplicazione per 2. 2*5 = 10.

Link al commento
Condividi su altri siti

intendi in formato esadecimale ?

se la risposta è no non serve che tu legga oltre

se il tuo micro ha l'istruzione moltiplicazione (es. 8051) è semplice

mul r1,#10 ; moltiplica decine*10

add r1,r2

in realtà il risultato della mul si trova su 16bit devi vedere tu (es 8051 us la coppia registri AB) di conseguenza l'addizione delle unità sarà una add 16bit non solo 8bit

puoi anche utilizzare solo l'istruzione shift poichè 10=8+2

prendi le decine shift di 3 a sinistra e metti in parte

riprendi le decine shift di 2 a sinistra e sommi con il precedente

poi sommi le unità

Link al commento
Condividi su altri siti

Grazie Livio

Ho gia letto qualche cosa di simile da te postato tempo fa.

Pensavo che ci fosse un sistema migliore a quello di trasformare la moltiplicazione in addizione.

Cosa pensi della mia soluzione?

Ciao e grazie

Link al commento
Condividi su altri siti

Anche questo è un micro che conosco piuttosto bene, anche se uso programmare in "C" con magari qualche istruzione in asm per ottimizzare la velocità o la lunghezza.

Purtroppo niente mul. O fai come ti ho detto io o fai come ti ha detto accacca.

C'è però un particolare a sfavore del sistema proposta do accacca, particolare dovuto a questo micro.

Non ha l'istruzione di shift ma quella di rotazione. COncettualmente cambia pco, solo che lo shift sposta a sx o a dx e butta fuori l'ultimo bit, il rotate, invece lo fa girare attraverso il carry, quindi prima diogni rotazione devi pulire il bit di carry. A questo punto conviene far le 5 somme (ecco il perchè del consiglio).

Comunque se non hai l'istruzione Hw di moltiplicazione e divisione ei costretto ad usare shift e somme, non è possibile fare altrimenti. Se analizzi le routines di moltiplicazione-divisione software son fatte con questa metodologia.

Daltronde in matematica esiste una sola operazione: la somma. Tutte le altre sono casi particolari della somma: somma di un numero negativo con uno positivo (sottrazione), somme ricorsive (moltiplicazione), sottrazioni ricorsive (divisione) e via elencando.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

Grazie ancora a tutti!!!

Però mi piacerebbe che analizzaste la soluzione da me proposta e mi diceste cosa ne pensate! (sull MPLAB funziona)

Ciao a tutti da ziopolly

Link al commento
Condividi su altri siti

  • 1 month later...

Le soluzioni sono di due tipi e profondamente diverse: o calcoli il prodotto via SW oppure, se ti serve velocità e/o se hai memoria libera puoi compilare una LUT.

http://it.wikipedia.org/wiki/Look-Up_Table

In pratica crei una tabella e usi i due dati come indice e dentro ci trovi il risultato, semplicemente un tabulato che mette in relazione precalcolata il risultato con il dato di partenza.

Vista la semplicità si possono anche efficientemente mischiare i due metodi: con una LUT di 10 elementi moltiplichi le decine, e poi le sommi alle unità.

Non conosco i PIC, ma un caricamento indicizzato l'hanno di sicuro, metti come indice le decine ed esplori la LUT, estratto il valore in unità (binarie) delle decine ci sommi le unità ed il gioco è fatto, forse addirittura più efficiente, oltre che per velocità, pure come LUNGHEZZA in byte LUT compresa!

Modificato: da ludo69
Link al commento
Condividi su altri siti

  • 2 weeks later...

ritorno sopra questa discussione perchè mi ronzava in mente una soluzione che ho messo a fuoco:

prendi il valore delle DECINE e shiftalo a sx di due posizioni, equivale a moltiplicarlo per quattro, poi sommaci ancora le decine e quindi il risultato è il prodotto per cinque, shifta ancora una volta e ciò che ottieni è il prodotto per dieci.

Ricorda che negli shift devono "entrare" da dx solo zeri, quindi occhio ad eventuali impilature dal carry.

La soluzione è piuttosto razionale anche perchè non deve impiegare registri/memorie per contenere risultati parziali, inoltre il numero di operazioni è limitato al (spero) minimo....

Link al commento
Condividi su altri siti

Decine: (000YXXXX)b

CARICA IN A,"DECINE"

AZZERA CARRY

RUOTA A, SX

RUOTA A, SX

SOMMA A CON "DECINE"

RUOTA A, SX

SOMMA A CON "UNITA'"

CARICA IN "RISULTATO",A

I bit più alti di DECINE deve essere zero altrimenti dall'operazione di rotazione rientrerebbero impropriamente "1" nella parte bassa del risultato, se il micro implementa degli shift senza rientro del carry allora si può evitare "AZZERA CARRY".

Dopo "AZZERA CARRY" e fino alla fine NON è prevista la possibilità di settaggio del CARRY, quindi l'azzeramento NON viene ripetuto, occhio che se metti un numero in "DECINE" maggiore di 25 oppure (decine=25 e UNITA'>5) allora viene generato un carry dovuto all'errore del contenuto dei dati.

In realtà il limite del valore contenuto nel formato decimale è espresso dal limite del risultato finale che è 255, quindi DECINE è compreso tra zero e 25, unità tra 0 e 9 (per rispetto della cardinalità decimale, altrimenti non ci sono limiti se non quelli del possibile risultato senza generazione del CARRY) ma se DECINE=25 allora unità deve essere ugual minore di 5.

Spero di essermi spiegato.....

Modificato: da ludo69
Link al commento
Condividi su altri siti

... e bravo Ludo69...

mi sembra che tu abbia elaborato una simpatica soluzione!

Peccato che ora io sia fuori sede (circa 10000 Km) ed abbia sospeso i giochi (così chiamo il mio hobby preferito dedicato all'elettronica).

Mi riprometto però, che al mio rientro (30 Aprile) proverò sicuramente la tua soluzione e non mancherò di farti sapere.

grazie ancora

ziopolly

Link al commento
Condividi su altri siti

  • 2 weeks later...

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...