View Full Version : [assembly 68k] Aiuto esercizi esame semplice btst o mascheramento bit?
s.stendardo
08-02-2013, 07:14
Contare quanti numeri con bit 3=0 diversi da D0
Contare quanti numeri maggiori di D5 con bit5=1
Sommare i numeri maggiori di 50 pari e con bit1=0
Sommare i numeri maggiori di D0 dipari e con bit1=1
Ovviamente sono tutti inseriti in un ciclo , con implementazione di un opportuno contatore
che conta solo se la condizione e' vera,
per dimostrare questi condizioni prendendo d'esempio
Contare quanti numeri maggiori di D5 con bit5=1
basta effettuare un semplice
dopo aver verificato che l'elemento analizzato e' maggiore di D5
BTST #5,D5
BEQ THEN
THEN CMP #1,D5
BEQ CONTA
oppure
Contare quanti numeri con bit 3=0 diversi da D0
dopo aver verificato che l'elemento analizzato e' diverso da D0
BTST #3,D0
BEQ THEN
THEN CMP #0,D0
BNE CONTA
Oppure effettuare un mascheramento e in tal caso come si potrebbe procedere?
tutti gli altri esercizi sono di facile comprensione , solo questa tipologia mi sento un po confuso
grazie a tutti in anticipo
cdimauro
08-02-2013, 08:40
Usa la BTST, che è decisamente più leggibile.
Potresti usare una bitmask in questo modo:
- precarichi un registro dati con la maschera giusta. Ad esempio MOVEQ #8,D1 carica in D1 la maschera di bit per selezionare esclusivamente il bit 3 (che ha "peso" pari a 8);
- copia il dato in un registro temporaneo, che puoi distruggere. Esempio: MOVE.L D5, D7
- esegui un and con la maschera: AND.L D1,D7
- controlli se il risultato è zero oppure non zero, sempre con BEQ o BNE.
La soluzione con la bitmask sarebbe più efficiente se il dato si potesse distruggere. Nello specifico, visto che fai diversi controlli, ti conviene rimanere con la BTST.
s.stendardo
08-02-2013, 18:08
grazie per la disponibilita cdimauro :-)
solo una cosa quindi volendo utilizzare un semplice btst
per un esercizio del genere verrebbe cosi'
Contare quanti numeri maggiori di D5 con bit5=1
----------------------------------------------------------------------
ciclo .................. *ovviamente c'e una condizione di uscita
CMP elemento,d5
blo then
else jmp ciclo++
then btst #5,elemento
beq vero
falso jmp ciclo++
vero cmp #1,elemento
beq conta
else2 jmp ciclo++
conta add.b #1,cont
----------------------------------------------------------------------
potrebbe andare bene cosi?
oppure devo fare un and a bit con un mascheramento
in tal caso potresti perdere 2 minuti per farmelo capire o vedere
ti ringrazio anticipatamente per la disponibilita data saluti
Usa la BTST, che è decisamente più leggibile.
Potresti usare una bitmask in questo modo:
- precarichi un registro dati con la maschera giusta. Ad esempio MOVEQ #8,D1 carica in D1 la maschera di bit per selezionare esclusivamente il bit 3 (che ha "peso" pari a 8);
- copia il dato in un registro temporaneo, che puoi distruggere. Esempio: MOVE.L D5, D7
- esegui un and con la maschera: AND.L D1,D7
- controlli se il risultato è zero oppure non zero, sempre con BEQ o BNE.
La soluzione con la bitmask sarebbe più efficiente se il dato si potesse distruggere. Nello specifico, visto che fai diversi controlli, ti conviene rimanere con la BTST.
s.stendardo
09-02-2013, 14:22
Up nessuno mi puo dare una mano venerdi ho l'esame ....
cdimauro
09-02-2013, 16:15
Cerco di darti una mano, anche se ancora non sto bene, e giovedì ho l'udienza in tribunale con la mia ex-azienda, per cui puoi capire che non sono messo proprio bene nemmeno io in questo periodo nero.
Comunque ti consiglio di lasciar perdere l'approccio con bitmask, come ti avevo già suggerito prima, e ricorri esclusivamente a BTST. A maggior ragione, visto che mi sembra di aver capito che sei poco pratico e un po' confuso, soluzioni semplici e chiare devono essere per te l'obiettivo principale. NON pensare a soluzione raffinate, ma sbrigative e funzionanti.
Altra cosa, per favore evita di mischiare pseudocodice con assembly 68000: viene fuori un pastrocchio illeggibile, che non giova a nessuno.
Col primo messaggio eri andato quasi bene. Ti riscrivo la seconda in maniera pulita e corretta, visto che già l'avevi abbozzata, così la puoi prendere come punto di partenza:
BTST #3,D1 ; Controlla se il bit 3 del numero è a zero.
BNE.S Loop ; Non è zero, quindi va scartato.
CMP.L D1,D0 ; Controlla se il numero coincide con D0.
BEQ.S Loop ; Sì, quindi va scartato.
; OK, la condizione è soddisfatta. Adesso provvedi a fare ciò che è previsto in questo caso
Sto supponendo che il registro D1 contenga il numero, e che sia a 32 bit (longword; da cui il suffisso .L nella CMP).
Ovviamente questo pezzo di codice vale esclusivamente per il controllo della condizione da esaminare.
Adesso devi aggiungere il codice per:
- aggiornare il conteggio (subito dopo);
- inizializzare il contatore (ovviamente molto prima);
- caricare il valore (prima);
- passare all'elemento successivo, se c'è.
Ogni tanto darò un'occhiata al forum per vedere se hai risposto. Considera, però, che NON ti posso risolvere l'esercizio, sia per policy del sito (è vietato), sia perché comunque non lo farei per una questione di deontologia professionale. Anche perché devi essere tu a imparare, e vorrei che arrivassi con le tue gambe alla soluzione: se capisci come fare, ti sarà facile affrontare qualunque problema. ;)
s.stendardo
09-02-2013, 19:59
Grazie caro , se la cosa ti puo consolare purtoppo un brutto periodo per tutti,
mio padre dopo tanti anni di lavoro in un spa e' licenziato io da 8 ore in un call center sono passato a 4 , ho 25 anni mi mancano una 10ina di esami per laurearmi quindi quando posso seguo i corsi e cerco nella laurea una rivalsa sociale, anche se e' difficile le aziende che sia una software house, o metalmeccanica se ne approfittano sempre succhiandoti anche l'anima e chi va avanti sono i soliti leccaculo e raccomandati con allacci politici... auguri per la tua causa mio padre dopo 4 anni c'e l'ha fatta e ha avuto il risarcimento.
tornando a noi se potevi dare un occhiata al codice grazie mille saluti
Traccia esercizio
DA 8100 A 8150
Contare quanti numeri con bit 3=0 diversi da D0
dopo aver verificato che l'elemento analizzato e' diverso da D0
ORG $8000
INIZIO CLR D0
CLR CNT
LOOP MOVE $8100,A0
CMP $8150,A0
BEQ FINE
THEN CMP (A0),D0
BNE TEST
ELSE ADD #2,A0
JMP LOOP
TEST BTST #3,(A0)
BEQ CONT
ELSE1 ADD #2,A0
JMP LOOP
CONT ADD #1,CNT
ADD #2,A0
JMP LOOP
FINE STOP #$8300
ORG $8000
CNT DS.W 1
END INIZIO
Cerco di darti una mano, anche se ancora non sto bene, e giovedì ho l'udienza in tribunale con la mia ex-azienda, per cui puoi capire che non sono messo proprio bene nemmeno io in questo periodo nero.
Comunque ti consiglio di lasciar perdere l'approccio con bitmask, come ti avevo già suggerito prima, e ricorri esclusivamente a BTST. A maggior ragione, visto che mi sembra di aver capito che sei poco pratico e un po' confuso, soluzioni semplici e chiare devono essere per te l'obiettivo principale. NON pensare a soluzione raffinate, ma sbrigative e funzionanti.
Altra cosa, per favore evita di mischiare pseudocodice con assembly 68000: viene fuori un pastrocchio illeggibile, che non giova a nessuno.
Col primo messaggio eri andato quasi bene. Ti riscrivo la seconda in maniera pulita e corretta, visto che già l'avevi abbozzata, così la puoi prendere come punto di partenza:
BTST #3,D1 ; Controlla se il bit 3 del numero è a zero.
BNE.S Loop ; Non è zero, quindi va scartato.
CMP.L D1,D0 ; Controlla se il numero coincide con D0.
BEQ.S Loop ; Sì, quindi va scartato.
; OK, la condizione è soddisfatta. Adesso provvedi a fare ciò che è previsto in questo caso
Sto supponendo che il registro D1 contenga il numero, e che sia a 32 bit (longword; da cui il suffisso .L nella CMP).
Ovviamente questo pezzo di codice vale esclusivamente per il controllo della condizione da esaminare.
Adesso devi aggiungere il codice per:
- aggiornare il conteggio (subito dopo);
- inizializzare il contatore (ovviamente molto prima);
- caricare il valore (prima);
- passare all'elemento successivo, se c'è.
Ogni tanto darò un'occhiata al forum per vedere se hai risposto. Considera, però, che NON ti posso risolvere l'esercizio, sia per policy del sito (è vietato), sia perché comunque non lo farei per una questione di deontologia professionale. Anche perché devi essere tu a imparare, e vorrei che arrivassi con le tue gambe alla soluzione: se capisci come fare, ti sarà facile affrontare qualunque problema. ;)
cdimauro
09-02-2013, 21:05
Ci siamo quasi. Ti metto delle indicazioni nei punti che devi cambiare, come commenti nel codice:
ORG $8000
INIZIO CLR D0
CLR CNT
LOOP MOVE $8100,A0 ; Le istruzioni che operano sugli indirizzi vanno sempre usate con suffisso .L (non è sempre vero, ma non voglio confonderti: assumi che sia così, a scopo didattico).
; Inoltre qui hai sbagliato modalità d'indirizzamento: questa è quella assoluta, per cui il processore caricherebbe dall'indirizzo $8100 la word, e la copierebbe in A0.
;Devi usare, invece, l'indirizzamento immediato (con # davanti).
CMP $8150,A0 ; Idem come sopra.
BEQ FINE
THEN CMP (A0),D0
BNE TEST
ELSE ADD #2,A0 ; Le istruzioni sugli indirizzi devono essere .L.
JMP LOOP
TEST BTST #3,(A0) ; Il test sui bit in memoria funziona soltanto su singolo byte.
; Poiché i 68000 sono big endian, in questo modo controlleresti il bit #11 anziché il #3 della word a cui punta (A0).
; Hai 2 soluzioni. La prima è che usi 1(A0) per puntare al byte di cui vuoi controllare il bit #3.
; La seconda è caricare la word in un registro, e poi eseguire il BTST con #3.
BEQ CONT
ELSE1 ADD #2,A0 ; Le istruzioni sugli indirizzi devono essere .L.
JMP LOOP
CONT ADD #1,CNT
ADD #2,A0; Le istruzioni sugli indirizzi devono essere .L.
JMP LOOP
FINE STOP #$8300
ORG $8000 ; A questo indirizzo hai caricato l'inizio del codice. Usa un'altra locazione, tipo $8200.
CNT DS.W 1
END INIZIO
Dopo aver effettuato le correzioni indicate, il codice dovrebbe funzionarti correttamente.
Premetto che non è affatto ottimizzato, e non stai usando una preziosa modalità d'indirizzamento dei 68000, per i quali sono noti e ancora oggi apprezzati (e sognati): quella di autoincremento (A0)+.
Non so come si comporterebbe il professore vedendo che non usi un cosa che per un programmatore 68000 è ovvia: è il suo pane quotidiano.
Personalmente mi farebbe storcere il naso. Però, tolto questo, e con le correzioni, il codice funzione. Per cui a mio avviso te la caveresti lo stesso, ma magari non col massimo dei voti.
P.S. La mia causa sarà molto lunga, anche perché non è la sola: ne sto preparando un altro paio. Ho subito troppi torti, e voglio giustizia, anche se ci vorrà parecchio tempo.
Nel frattempo sono 14 mesi che sono fermo. In Sicilia non è facile trovare lavoro, e il conto in banca diminuisce vistosamente. Anche se ho fatto la formichina e messo da parte un bel po', senza altre entrate non potrà che arrivare a toccare il fondo.
Comunque sono fiducioso che qualche progetto personale a cui ho speso il mio tempo possa magari dare i frutti sperati. Incrocio le dita...
In bocca al lupo anche a te!
s.stendardo
09-02-2013, 22:23
Affinandolo un pochetto dovrebbe venire cosi...
ORG $8000
INIZIO CLR D0
CLR D1
CLR CNT
MOVE.L #$8100,A0
LOOP CMP.L #$8150,A0
BEQ FINE
THEN MOVE.B (A0)+,D1
CMP.B D1,D0
BNE TEST
ELSE JMP LOOP
TEST BTST #3,D1
BEQ CONT
ELSE1 JMP LOOP
CONT ADD #1,CNT
JMP LOOP
FINE STOP #$8300
ORG $8400
CNT DS.B 1
END INIZIO
Ci siamo quasi. Ti metto delle indicazioni nei punti che devi cambiare, come commenti nel codice:
ORG $8000
INIZIO CLR D0
CLR CNT
LOOP MOVE $8100,A0 ; Le istruzioni che operano sugli indirizzi vanno sempre usate con suffisso .L (non è sempre vero, ma non voglio confonderti: assumi che sia così, a scopo didattico).
; Inoltre qui hai sbagliato modalità d'indirizzamento: questa è quella assoluta, per cui il processore caricherebbe dall'indirizzo $8100 la word, e la copierebbe in A0.
;Devi usare, invece, l'indirizzamento immediato (con # davanti).
CMP $8150,A0 ; Idem come sopra.
BEQ FINE
THEN CMP (A0),D0
BNE TEST
ELSE ADD #2,A0 ; Le istruzioni sugli indirizzi devono essere .L.
JMP LOOP
TEST BTST #3,(A0) ; Il test sui bit in memoria funziona soltanto su singolo byte.
; Poiché i 68000 sono big endian, in questo modo controlleresti il bit #11 anziché il #3 della word a cui punta (A0).
; Hai 2 soluzioni. La prima è che usi 1(A0) per puntare al byte di cui vuoi controllare il bit #3.
; La seconda è caricare la word in un registro, e poi eseguire il BTST con #3.
BEQ CONT
ELSE1 ADD #2,A0 ; Le istruzioni sugli indirizzi devono essere .L.
JMP LOOP
CONT ADD #1,CNT
ADD #2,A0; Le istruzioni sugli indirizzi devono essere .L.
JMP LOOP
FINE STOP #$8300
ORG $8000 ; A questo indirizzo hai caricato l'inizio del codice. Usa un'altra locazione, tipo $8200.
CNT DS.W 1
END INIZIO
Dopo aver effettuato le correzioni indicate, il codice dovrebbe funzionarti correttamente.
Premetto che non è affatto ottimizzato, e non stai usando una preziosa modalità d'indirizzamento dei 68000, per i quali sono noti e ancora oggi apprezzati (e sognati): quella di autoincremento (A0)+.
Non so come si comporterebbe il professore vedendo che non usi un cosa che per un programmatore 68000 è ovvia: è il suo pane quotidiano.
Personalmente mi farebbe storcere il naso. Però, tolto questo, e con le correzioni, il codice funzione. Per cui a mio avviso te la caveresti lo stesso, ma magari non col massimo dei voti.
P.S. La mia causa sarà molto lunga, anche perché non è la sola: ne sto preparando un altro paio. Ho subito troppi torti, e voglio giustizia, anche se ci vorrà parecchio tempo.
Nel frattempo sono 14 mesi che sono fermo. In Sicilia non è facile trovare lavoro, e il conto in banca diminuisce vistosamente. Anche se ho fatto la formichina e messo da parte un bel po', senza altre entrate non potrà che arrivare a toccare il fondo.
Comunque sono fiducioso che qualche progetto personale a cui ho speso il mio tempo possa magari dare i frutti sperati. Incrocio le dita...
In bocca al lupo anche a te!
cdimauro
10-02-2013, 08:30
Ottimo.
Se inverti le condizioni puoi eliminare i primi due JMP LOOP e lasciare soltanto l'ultimo. Ma queste sono finezze, eh! Il tuo codice va benissimo già così.
s.stendardo
12-02-2013, 20:00
Grazie mille caro auguri di tutto ti mando delle benedizioni :-)
di questi periodi ti possono essere utili... :-):D
Ottimo.
Se inverti le condizioni puoi eliminare i primi due JMP LOOP e lasciare soltanto l'ultimo. Ma queste sono finezze, eh! Il tuo codice va benissimo già così.
cdimauro
12-02-2013, 20:35
Grazie per il pensiero. Incrocio le dita per dopodomani mattina, davanti al giudice del lavoro. :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.