PDA

View Full Version : [Assembly] Domanda varie


Bandit
07-09-2005, 20:19
Sto studiando un pò di programma assembler per il Motorola 68000, non so se servono queste informazioni, ma ve le ho dette. In questo momento vi pongo solo una domanda, nonostante il titolo, ma essendo solo all'inizio dello studio, ce ne potrebbero essere delle altre.

La codifica dell'istruzione MOVE B,D2 è costituita da una stringa di quanti bit?
Dovrebbe venire 48 bit, perchè quale è il ragionamento?

Il mio ragionamento: visto che dopo il move non c'è il ".B o .L o .W" non si può dire, ma non è così vedendo il risulatato perchè?

ciao spero vivamente nel vostro aiuto

cdimauro
08-09-2005, 11:33
MOVE B,D2 è codificata usando 6 byte (48 bit), perché l'opcode contiene:
- 2 byte per l'istruzione;
- 4 byte per l'indirizzo assoluto della variabile B.

Quando non è presente alcun suffisso nell'istruzione, s'intende sempre .W, quindi una word (16 bit).

Bandit
08-09-2005, 11:37
e D2 non si considera?

"2 byte per l'istruzione", si riferisca a move? e vale per qualsiasi istruzione assembler?

" 4 byte per l'indirizzo assoluto della variabile B." E' sempre così?


;) ciao

cdimauro
08-09-2005, 12:33
D2 non si considera perché è "inglobato" nell'opcode.

Ogni istruzione è costituita da almeno 2 byte, che ne denotano la tipologia e da cui è possibile capire se sono necessarie altri byte (sempre 2 alla volta: tutte le istruzioni hanno una lunghezza pari).

Nel tuo caso i primi 2 byte indicano che si tratta di una
MOVE.W IndirizzoAssoluto,D2

Quindi si capisce che per completare l'istruzione serve conoscere l'indirizzo assoluto da leggere. Questo si trova, appunto, nei 4 byte che seguono.

Bandit
08-09-2005, 12:47
D2 non si considera perché è "inglobato" nell'opcode.

Ogni istruzione è costituita da almeno 2 byte, che ne denotano la tipologia e da cui è possibile capire se sono necessarie altri byte (sempre 2 alla volta: tutte le istruzioni hanno una lunghezza pari).



quindi da come mi dici ci sono anche istruzioni per esempio di 4 byte? mi fai un esempio.


poi hai capito che era indirizzo assoluto dalla B?


e poi se il move era ad esempio
MOVE.L B,D2
MOVE.W D1,D2
MOVE.W A0,D2
di quanti bit era l'istruzione?
scusa se ti faccio domande ma vorrei capire a pieno il ragionamento ;)

cdimauro
08-09-2005, 13:04
quindi da come mi dici ci sono anche istruzioni per esempio di 4 byte? mi fai un esempio.
Anche più di 4 byte: con l'architettura 68020+ si può arrivare a istruzioni lunghe fino a 22 byte. :D

Col 68000 mi sembra che il massimo si raggiunga con una
MOVE.L IndirizzoAssoluto,IndirizzoAssoluto
oppure
MOVE.L IndirizzoAssoluto,#Costante

E dovremmo essere sui 10 byte (2 di opcode, 4 per l'indirizzo assoluto, 4 per la costante nel secondo caso).

Istruzioni di 4 byte:
MOVE.W Registro,#Costante
MOVE.W (RegistroIndirizzi, RegistroDati.Lunghezza, Costante8Bit),Registro
ecc. ecc. ecc.
poi hai capito che era indirizzo assoluto dalla B?
Sì, perché è un identificatore, per cui serve il suo indirizzo per potervi accedere.
e poi se il move era ad esempio
MOVE.L B,D2
MOVE.W D1,D2
MOVE.W A0,D2
di quanti bit era l'istruzione?
48, 16 e 16 rispettivamente.
scusa se ti faccio domande ma vorrei capire a pieno il ragionamento ;)
Se ti serve veramente lavorare coi 68000 in assembly, direi che è meglio un piccolo corso di assembly 68000, piuttosto che delle "lezioni a rate". :D

Quanto meno ti fai un'idea sull'architettura, e man mano i tuoi dubbi si dissolveranno...

Comunque per me non c'è problema: sui 68000 c'ho lavorato per parecchi anni, per cui dovrei essere ancora in grado di darti una mano... :)

Bandit
08-09-2005, 13:12
grazie ;)
allora il problema mio è quello di sapere ad ogni cosa quanti bit corrispondono.
c'è una tabella a riguardo? o se è breve me la potresti fare tu.

per esempio come mai MOVE.L B,D2 è sempre di 48 bit se c'è il .L? perchè B è indirizzo assoluto e quindi qualunque cosa (.L/.W/.B) ci metti è sempre 16 bit.

cdimauro
08-09-2005, 13:18
Perché la dimensione del dato occupa 2 bit, che sono memorizzati all'interno dell'istruzione (nei primi 2 byte). :)

Una tabella sarebbe un po' lunghetta e francamente non mi ricordo nemmeno il pattern della NOP.

Comunque se cerchi su internet "68000 opcode table" o roba simile dovresti trovare tutto ciò che ti serve.

Al limite ti posso dare una mano se ti serve imparare a programmare in assembly 68000, ma una guida veloce di riferimento comunque ti serve.

Bandit
08-09-2005, 13:21
ho l'instruction set, ma non mi sembra di averlo visto.

Bandit
08-09-2005, 13:23
ho trovato questo ma come si legge? c'entra o non c'entra?
http://goldencrystal.free.fr/M68kOpcodes.pdf

cdimauro
09-09-2005, 10:57
Sì, è quella la tabella. Molto compatta, ma dovrebbe bastare per tirare fuori gli opcode delle istruzioni che ti servono.

Per curiosità: ma tu non hai intenzione di imparare a programmare i 68000, giusto? Perché in genere non interessa assolutamwnte lo studio degli opcode...

Bandit
09-09-2005, 11:40
devo saper la parte teorica ed un pò di pratica

Bandit
09-09-2005, 11:53
Ho purtroppo un altra domanda: Le estensioni dei due indirizzi su 16 bit $2011 e $C044 su indirizzi a 32 bit generano rispettivamente gli indirizzi......quale indirizzi generano? il risultato è

$00002011 e $FFFFC044, perchè?
Ho ragionato così: vengono aggiunti solo degli zeri all'inizio che non hanno nessun significato... non capisco quindi come faccia a risultare FFFF all'inizio del secondo....... :muro: :muro: :muro:

cdimauro
09-09-2005, 11:54
Ho capito: hai qualche esame da sostenere... :)

Per qualunque cosa, chiedi pure: compatibilmente coi miei impegni vedrò di aiutarti...

cdimauro
09-09-2005, 11:56
Ho purtroppo un altra domanda: Le estensioni dei due indirizzi su 16 bit $2011 e $C044 su indirizzi a 32 bit generano rispettivamente gli indirizzi......quale indirizzi generano? il risultato è

$00002011 e $FFFFC044, perchè?
Ho ragionato così: vengono aggiunti solo degli zeri all'inizio che non hanno nessun significato... non capisco quindi come faccia a risultare FFFF all'inizio del secondo....... :muro: :muro: :muro:
Hai usato l'indirizzamento assoluto "corto" (che usa soltanto 16 bit).
In questo caso il bit più significativo dei 16 bit viene preso, e copiato nei 16 bit alti per formare l'indirizzo assoluto "completo", a 32 bit.

E' tutto normale, non ti preoccupare.

Bandit
09-09-2005, 12:15
Rispondo ai 2 interventi precedenti, ringraziandoti della disponibilità, anche se spero di far meno domande possibili, perchè le cose preferisco capirle e risolverle con gli "strumenti" che ho (anche perchè credo di fare + rapidamente), quindi se faccio delle domande è proprio perchè non so dove mettere le mani e spero che qualche anima pia (come te) possa darmi una mano. ;)


Ritornando alla domanda:
perchè partendo da $2011 e $C044 si arriva a $00002011 e $FFFFC044?

nel primo, il bit + significativo è 2, perchè viene esteso con lo zero?
e nel secondo, perchè con la F se il bit + significativo + C?

cdimauro
09-09-2005, 12:27
$2 e $C sono i nibble (più significativi), quindi un gruppo di 4 bit, e non un bit.
$2 = %0010 -> bit più significativo (il più a sinistra) = 0
$C = %1100 -> bit più significativo (idem come sopra) = 1

Bandit
09-09-2005, 12:36
quindi devo estendere il nibble + significativo, su 4 bit....


p.s. ma il nibble è metà di qualcosa, giusto? mi sembra nibble=1/2 byte

cdimauro
09-09-2005, 12:42
Sì, il nibble è mezzo byte.

Non devi estendere il nibble, ma il bit più significativo. Per semplificare, se vuoi ottenere i 16 bit sotto forma di nibble, ti basta fare questo:
MSB = %0 -> nibble = %0000 = $0 -> 16 bit alti = $0000
MSB = %1 -> nibble = %1111 = $F -> 16 bit alti = $FFFF

Bandit
09-09-2005, 12:46
si si avevo sbagliato a digitare ;)

ok credo di aver capito, grazie

Bandit
12-09-2005, 18:23
In seguito all'esecuzione del seguente programma assembly, quanto vale il registro D0?
ORG $8000
START MOVE.W A,D0
MOVEA.L #B,A0
ADD.W (A0)+,D0
JMP SYSA

A DC.W $10
B DC.W 8
SYSA EQU $1000
END START

cioè come faccio a calcolarmelo?
A vale 16


p.s se poniamo A DC.W 1, dopo l'esecuzione dell'istruzione MOVE.L #A,A0 il registro A0 conterrà, l'indirizzo di memoria corrispondente all'etichetta A; quando poniamo MOVEA.L #A,A0 , A0 cosa contiene?

cdimauro
13-09-2005, 11:35
In seguito all'esecuzione del seguente programma assembly, quanto vale il registro D0?
ORG $8000
START MOVE.W A,D0
MOVEA.L #B,A0
ADD.W (A0)+,D0
JMP SYSA

A DC.W $10
B DC.W 8
SYSA EQU $1000
END START
cioè come faccio a calcolarmelo?
A vale 16
Quindi d0 = 16 dopo la move. A0 punta a B, che vale 8. Quindi la add produce $10 + 8 = $18 = 24.
p.s se poniamo A DC.W 1, dopo l'esecuzione dell'istruzione MOVE.L #A,A0 il registro A0 conterrà, l'indirizzo di memoria corrispondente all'etichetta A; quando poniamo MOVEA.L #A,A0 , A0 cosa contiene?
Sempre l'indirizzo di memoria di A. :)

Bandit
13-09-2005, 11:47
MOVEA.L #B,A0


A0 punta a B lo si capisce da questa istruzione,giusto?

quindi il jump Sysa non serve a nulla? possiamo anche non considerarlo?

cdimauro
13-09-2005, 12:21
A0 punta a B lo si capisce da questa istruzione,giusto?
Sì, perché carichi in A0 il "valore" di B, cioé il suo indirizzo...
quindi il jump Sysa non serve a nulla? possiamo anche non considerarlo?
Beh, non so cosa dovrebbe fare esattamente questo codice. Se SysA è l'indirizzo di una funzione del s.o. per far terminare un task, questo salto sicuramente ci vuole. Altrimenti potrebbe bastare una RTS o altro.

Bandit
13-09-2005, 12:24
ok grazie ancora

Bandit
16-09-2005, 13:25
il passaggio di questa istruzione nei flag N, V, C cosa comporta?

Move #$FFF0,Do
ADD #$F016,Do

il riporto (C) sicuramente,poi forse anche N visto che i bit + significativi sono alti e per V?


Oggi ho scoperto che la rappresentazione in Binary Code D....su 8 bit si fa così:
per esempio 32 3=0011 2=0010 ------>32=00110010
ma allora come si chiama la rappresentazione di 32 così: 01000000?

ciao

Bandit
16-09-2005, 13:34
Ho un 'istruzione C++ pari a void (int VETT1,int VETT2,int riemp, int &min,int &mag)
gli offsett come si devono mettere, dopo aver inizializzato il frame pointer e salvato l'indirizzo di ritorno sullo stack?

VETT1 offset 8
VETT2 " 10
riemp " 12
min "
mag "

e poi?

cdimauro
19-09-2005, 11:30
il passaggio di questa istruzione nei flag N, V, C cosa comporta?

Move #$FFF0,Do
ADD #$F016,Do

il riporto (C) sicuramente,poi forse anche N visto che i bit + significativi sono alti e per V?
Anche V dovrebbe essere settato, perché se ho visto bene, il valore risultante, considerandolo come signed, eccede il range delle word signed.
Oggi ho scoperto che la rappresentazione in Binary Code D....su 8 bit si fa così:
per esempio 32 3=0011 2=0010 ------>32=00110010
ma allora come si chiama la rappresentazione di 32 così: 01000000?

ciao
Binaria. :)

La rappresentazione BCD serve ad altro, ma ormai è praticamente in disuso...

cdimauro
19-09-2005, 11:31
Ho un 'istruzione C++ pari a void (int VETT1,int VETT2,int riemp, int &min,int &mag)
gli offsett come si devono mettere, dopo aver inizializzato il frame pointer e salvato l'indirizzo di ritorno sullo stack?

VETT1 offset 8
VETT2 " 10
riemp " 12
min "
mag "

e poi?
Perché devi usare lo stack? Puoi mettere tutto nei registri: il 68000 ne ha ben 8 per i dati e 7 per gli indirizzi. ;)

Bandit
19-09-2005, 13:33
Perché devi usare lo stack? Puoi mettere tutto nei registri: il 68000 ne ha ben 8 per i dati e 7 per gli indirizzi. ;)
e considerando lo stack?

Bandit
19-09-2005, 13:34
Anche V dovrebbe essere settato, perché se ho visto bene, il valore risultante, considerandolo come signed, eccede il range delle word signed.

Binaria. :)



quindi 111?
se era unsigned?011?

cdimauro
20-09-2005, 10:14
e considerando lo stack?
In C/C++ normalmente gli argomenti vengono "pushati" :rolleyes: nello stack in ordine inverso.

le istruzioni di push dovrebbero essere le seguenti:


pea mag
pea min
move.l #riemp,-(sp)
move.l #VETT2,-(sp)
move.l #VETT1,-(sp)

Poi c'è la jsr alla routine, che dovrebbe avere il seguente entry point:

move.l sp,a6

A questo punto, supponendo che a6 sia il frame pointer, per accedere agli argomenti gli offset dovrebbero essere i seguenti:

VETT1 = 4
VETT2 = 8
riemp = 12
min = 16
mag = 20

E' da molto che non programmo in assembly 68000, quindi prendi tutto col beneficio del dubbio... :p

cdimauro
20-09-2005, 10:16
quindi 111?
se era unsigned?011?
Che il dato sia intero come signed o unsigned è indifferente. Se i flag sono mappati come NVC, il risultato dovrebbe essere sempre 111.

Bandit
20-09-2005, 11:10
In C/C++ normalmente gli argomenti vengono "pushati"

VETT1 = 4
VETT2 = 8
riemp = 12
min = 16
mag = 20

E' da molto che non programmo in assembly 68000, quindi prendi tutto col beneficio del dubbio... :p

cioè fino a 12, forse l'avevo capito anche io, il fatto che non ho capito il 16 ed il 20. Min e mag sono 2 longword?

ciao ;)

cdimauro
20-09-2005, 11:16
Ho considerato sizeof(int) = 4 byte.

Coi 680x0 non è possibile effettuare push sullo stack di byte o di dimensioni dispari. In generale comunque è sempre meglio effettuare push di valori a 32 bit; eventualmente i push di word (2 byte) è meglio "accoppiarli" (farne due di seguito), in modo che il prossimo indirizzo risultante continui ad essere allineato a 32 bit...

Bandit
20-09-2005, 11:22
No cmq le risposte esatte almeno per quel che ti ho postato io all'inizio 8/10/12 sono quelle corrette volevo sapere però il resto

cdimauro
20-09-2005, 11:36
Se vuoi sapere come definire le costanti, ti basta usare EQU:

VETT1Offset EQU 4

Se è qualcos'altro, non ho capito.

Bandit
20-09-2005, 11:41
VETT1 offset 8
VETT2 " 10
riemp " 12
min "
mag "

Volevo sapere che numeri ci andavano dopo questi e per qual motivo.

p.s. le " stanno ad indicare offset ;)

cdimauro
20-09-2005, 11:56
VETT1 offset 8
VETT2 " 10
riemp " 12
min "
mag "

Volevo sapere che numeri ci andavano dopo questi e per qual motivo.

p.s. le " stanno ad indicare offset ;)
Fermo restando che per me i numeri sono 4, 8, 12, 16 e 20 rispettivamente per VETT1, VETT2, ecc. la giustificazione è la seguente:
1) il primo offset, 4, indica che il valore di VETT1 si trova esattamente dopo l'indirizzo di ritorno dalla subroutine;
2) tutti gli altri offset si ricavano partendo da questo, e sommando via via la dimensione delle variabili. VETT2 offset = VETT1 offset + sizeof(VETT1) = 4 + 4 = 8.

Se tu consideri sizeof(int) = 2, allora gli offset sono 4, 6, 8, 10, 14.

Bandit
20-09-2005, 19:08
si ma credo si parte da 8....


Cmq il problema è quanto sono grandi min e mag :confused: :confused: :confused:

cdimauro
21-09-2005, 10:59
Si parte da 4 perché prima nello stack c'è soltanto l'indirizzo di ritorno. Se invece la subroutine fa il push anche del registro usato come frame pointer (per poi ripristinarlo alla fine), chiaramente si partirà da 8.

Quanto a min e mag, essendo puntatori, occuperanno 4 byte.

Bandit
21-09-2005, 11:23
Quanto a min e mag, essendo puntatori, occuperanno 4 byte.

quindi una longword