home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti4 / 68000-1.txt next >
Text File  |  1998-09-21  |  26KB  |  632 lines

  1.  
  2. ;    TABELLA DI RIFERIMENTO DELLA PROGRAMMAZIONE 68000
  3.  
  4. Sinteticamente gli indirizzamenti:
  5.  
  6.  move.l #123,xxxx       ; Immediato: si mette nella destinazione il numero
  7.  move.l xxxx,$50000       ; Assoluto lungo
  8.  move.l xxxx,$500.w       ; Assoluto corto (meno di $7FFF)
  9.  move.l    xxxx,D0           ; Registro dati diretto
  10.  move.l    xxxx,A0           ; Registro indirizzi diretto
  11.  move.l    xxxx,(a0)       ; Registro indirizzi indiretto
  12.  move.l    xxxx,(a0)+       ; Registro indirizzi indiretto con post-incremento
  13.  move.l    xxxx,-(a0)       ; Registro indirizzi indiretto con pre-decremento
  14.  move.l    xxxx,$123(a0)       ; Reg. indirizzi ind. con OFFSET (distanza di ind.)
  15.  move.l    xxxx,$12(a0,d0.w)  ; Reg. indirizzi ind. con OFFSET e INDICE
  16.  move.l offset(PC),xxxx       ; Relativo al PC con OFFSET
  17.  move.l offset(PC,d0.w),xxxx ; Relativo al PC con OFFSET
  18.  
  19.             -    -    -
  20.  
  21. * Gli indirizzamenti piu' diversi si possono "MISCHIARE" nelle istruzioni
  22.   tra sorgente e destinazione, ad esempio "move.l -(a0),12(a0,d3.l)".
  23.  
  24.             -    -    -
  25.  
  26. * I numeri decimali non sono preceduti da nessun simbolo (es. 123), i numeri
  27.   esadecimali sono preceduti dal $ (es. $1a0) e comprendono anche le lettere
  28.   da A ad F, mentre i numeri binari sono preceduti dal simbolo % (es: %01011)
  29.   e sono composti da 0 e da 1 solamente (CORRENTE O MENO NEI FILI!!!).
  30.   La conversione tra i 3 sistemi di numerazione non presenta problemi, in
  31.   quanto basta usare il comando "?" dell'ASMONE seguito dal numero, e si
  32.   ottiene il risultato in decimale, esadecimale e ASCII, ossia in CARATTERI:
  33.   infatti anche le lettere come "ABCDabcd..." sono rappresentate da un byte
  34.   ciascuna. Per esempio la "Z" e' $5a (Provate con un ?"Z"). I caratteri si
  35.   indicano mettendoli tra virgolette (si usano "" oppure '') e si possono
  36.   usare sia nei comandi (MOVE.B #"a",LABEL1), sia mettendoli in memoria
  37.   con il DC.B, (es: DC.B "Un testo in memoria...").
  38.  
  39.             -    -    -
  40.  
  41. * In assembler la moltiplicazione si indica con *, la divisione con /, e
  42.   si possono usare parentesi tonde a volonta', ad esempio:
  43.   move.l #(100/2*(12+$41-32)+%01101010),RISULTATO
  44.  
  45.             -    -    -
  46.  
  47. * 1 byte = 8 bit ($00 = %00000000; $FF = %11111111)
  48.   1 word = 16 bit ($0000 = %0000000000000000; $FFFF = %1111111111111111)
  49.   1 long = 32 bit, ossia 2 words ($00000000 = %000000000000000000000000000000)
  50.  
  51.             -    -    -
  52.  
  53. * I bit si contano partendo da 0 da destra verso sinistra: ad esempio
  54.   un byte che abbia il bit 5 ad 1 (ossia ALTO): %00100000. Un byte dunque
  55.   ha i bit che vanno dallo 0 (bit meno significativo) al settimo (bit piu'
  56.   significativo), una word va da 0 a 15, una longword da 0 a 31.
  57.   Per numerare facilmente i bit potete usare questo espediente:
  58.         ; 5432109876543210    - una word
  59.     move.l    #%1000010000110000,d0    ; bit 15,10,5 e 4 ALTI (ad 1)
  60.  
  61.             -    -    -
  62.  
  63. * Gli indirizzi si indicano per convenzione con numeri esadecimali
  64.  
  65.             -    -    -
  66.  
  67. * Istruzioni con il simbolo "#" come MOVE.L #123,d0, CMP.L #10,LABEL1 ecc
  68.   considerano il numero dopo il cancelletto come numero "COSTANTE" ossia
  69.   proprio come numero, non come indirizzo, a differenza di quando non e'
  70.   presente il cancelletto: move.b $12,$45 copia il byte nell'indirizzo $12
  71.   nell'indirizzo $45, mentre move.b #$12,$45 mette in $45 il numero $12.
  72.  
  73.             -    -    -
  74.  
  75. * I registri DATI e INDIRIZZI sono lunghi 32 bit, ossia una longword; sui
  76.   registri INDIRIZZI non si puo' lavorare col .b, ma solo col .w o .l
  77.  
  78.             -    -    -
  79.  
  80. * Non si puo' operare su indirizzi dispari con istruzioni .w o .l, ma solo
  81.   .b, as esempio un move.l #1,$10001 manda in GURU il computer, mentre un
  82.   move.b #1,$10001 non causa problemi
  83.  
  84.             -    -    -
  85.  
  86. * Un byte puo' contenere un numero da $00 a $ff, ossia 255, dopodiche' se si
  87.   fanno addizioni il numero riparte da zero, lo stesso vale per le word, il
  88.   cui numero massimo e' $FFFF, ossia 65535, e per le longword (max: $FFFFFFFF)
  89.  
  90.             -    -    -
  91.  
  92. * Le LABEL, i COMMENTI dopo i ; e i DC.W non sono istruzioni del 68000, ma
  93.   comandi dell'assemblatore utili per segnalare date posizioni del programma
  94.   o dei dati (LABEL), per inserire commenti utili alla comprensione del
  95.   listato, o per inserire direttamente bytes, word o longword in dati punti
  96.   della memoria (DC.W), si puo' verificare disassemblando la memoria con
  97.   il comando "D $xxxxx" o "D LABEL".
  98.  
  99. **    **    **    **    **    **    **    **    **    **    **
  100.  
  101. ;    INDIRIZZAMENTI DEL 68000 (Esempi)
  102.  
  103. ; Indirizzamenti con indirizzi assoluti, .L (Longword)
  104.  
  105.  move.l    #$123,$50000    ; mettiamo $00000123 in $50000 (infatti gli zeri a
  106.              ; sinistra sono opzionali, scrivere move.l #$123,xxxx
  107.              ; e' come scrivere move.l #$00000123,xxxx, in memoria
  108.              ; l'istruzione viene assemblata sempre con gli zeri).
  109.              ; DA NOTARE che con questa istruzione .l abbiamo
  110.              ; modificato 4 bytes (essendo una long lunga 4 bytes):
  111.              ; ossia gli indirizzi $50000,$50001,$50002,$50003,
  112.              ; dandogli i seguenti valori:
  113.              ; $50000 = $00
  114.              ; $50001 = $00
  115.              ; $50002 = $01
  116.              ; $50003 = $23
  117.  
  118.             -    -    -
  119.  
  120. ; Indirizzamenti con indirizzi assoluti, .W (Word)
  121.  
  122.  move.w    #$123,$50000    ; mettiamo $0123 in $50000 - Con questa istruzione .w
  123.              ; abbiamo modificato 2 bytes (essendo una word lunga 2
  124.              ; bytes): ossia gli indirizzi $50000 e $50001:
  125.              ; $50000 = $01
  126.              ; $50001 = $23
  127.  
  128.             -    -    -
  129.  
  130. ; Indirizzamenti con indirizzi assoluti, .B (Byte)
  131.  
  132.  move.b    #$12,$50000    ; mettiamo $12 in $50000 - Con questa istruzione .b
  133.              ; abbiamo modificato 1 byte, ossia solo $50000.
  134.              ; $50000 = $12
  135.             ; FATE MOLTA ATTENZIONE ALLE DIFFERENZE DI EFFETTI
  136.             ; CAMBIANDO SEMPLICEMENTE IL .L in .W o .B, infatti
  137.             ; spesso gli errori dei principianti sono nello
  138.             ; scambiare .w con .l o nella valutazione sbagliata
  139.             ; degli effetti di queste istruzioni. Usate il
  140.             ; debugger (comando "AD", poi tasto cursore >) per
  141.             ; verificare certe istruzioni e togliervi dubbi.
  142.  
  143.  move.l $40000,$50000    ; in questo caso copiamo il contenuto dei 4 bytes
  144.              ; $40000,$40001,$40002,$40003 nei 4 bytes $50000,
  145.              ; $50001,$50002,$50003, ad esempio:
  146.              ; se $40000= $00102304:
  147.              ; $50000 = $00
  148.              ; $50001 = $10
  149.              ; $50002 = $23
  150.              ; $50003 = $04
  151.             ; Allo stesso modo muovendo .w e .b copiamo da un
  152.             ; indirizzo ad un altro 2 bytes oppure 1 byte.
  153.  
  154.             -    -    -
  155.  
  156. NOTA: quando usiamo le LABEL per modificare dati in memoria l'assemblatore
  157. poi le converte negli indirizzi EFFETTIVI che le label rappresentano, dato
  158. che le LABEL sono usate per definire certe zone del programma, ad etichettare
  159. queste parti, per cui riferendoci alla LABEL in pratica ci riferiamo al punto
  160. dove e' messa la label stessa. Sono compresi dunque negli esempi precedenti
  161. di indirizzamenti assoluti istruzioni come:
  162.  
  163.     MOVE.L    LABEL1,$50000
  164.     MOVE.W    #$123,LABELBAU
  165.     MOVE.B    LABELCANE,LABELGATTO
  166.  
  167. Che in memoria saranno assemblate in maniera simile a questa:
  168.  
  169.     MOVE.L    $64230,$50000    ; supponiamo che LABEL1 fosse a $64230
  170.     MOVE.W    #$123,$726e0    ; supponiamo che LABELBAU fosse a $726e0
  171.     MOVE.B    $23450,$3a010    ; come sopra...
  172.  
  173. Dunque per i byte, le word e le longword indicate con le LABEL dovete ragionare
  174. come se fossero indirizzi, proprio perche' SONO ASSEMBLATE come indirizzi!!!!
  175.  
  176. E' per questo che un istruzione come questa:
  177.  
  178.     MOVE.L    #LABEL1,$dff080        ; Usata per "puntare" la copperlist
  179.  
  180. Mette in $dff080 l'indirizzo di LABEL1 anziche' copiare i 4 bytes posti
  181. dopo LABEL1: perche' LABEL1 viene convertita nel suo indirizzo, ed essendo
  182. posta dietro il simbolo del cancelletto (#), viene copiato come numero in
  183. $dff080, ossia nella destinazione... facciamo un esempio:
  184.  
  185.     MOVE.L    #LABEL1,LABEL2
  186.     MOVE.L    LABEL1,LABEL2
  187.     
  188. Sono assemblate come: (assumendo indirizzi ipotetici per le LABEL)
  189.  
  190.     MOVE.L    #$42300,$53120    ; viene messo in $53120 il numero $42300,
  191.                 ; ossia l'indirizzo della label
  192.     MOVE.L    $42300,$53120    ; viene copiata in $53120 la longword che
  193.                 ; si trova in $42300
  194.  
  195.  
  196.             -    -    -
  197.  
  198. NOTA2: E' possibile riferirci ad indirizzi assoluti sotto la word, ossia
  199. fino a $7FFF, in maniera piu' raffinata e veloce, aggiungendo un .w dopo
  200. l'indirizzo: e' il caso del MOVE.L 4.w,A6 che muove l'execbase in A6, ma
  201. qualsiasi istruzione che agisca su indirizzi di una WORD o di un BYTE puo'
  202. essere "scorciata" dei 4 zeri superflui di sinistra: vediamo la differenza:
  203.  
  204.                 (assemblata)
  205.     MOVE.B    #10,$123    -> MOVE.B #10,$00000123
  206.     MOVE.B    #10,$123.w    -> MOVE.B #10,$0123    - SENZA ZERI INUTILI
  207.  
  208. L'EFFETTO DELL'ISTRUZIONE NON CAMBIA!!! cambia solo la sua "FORMA", che appare
  209. piu' snella e veloce. Dimenticandosi di mettere il .w agli indirizzi "corti"
  210. semplicemente si produce un codice con qualche word in piu'.
  211.  
  212. **    **    **    **    **    **    **    **    **    **    **
  213.  
  214. ; Registri dati, .L (longword)
  215.  
  216.  move.l    #$123,d0    ; registro dati diretto (mettiamo $123 in d0)
  217.  
  218.  move.l    d1,d0        ; registro dati diretto (copiamo il valore di d1 in d0)
  219.  
  220. ; Registri dati, .w (word) (nota: si dice word "BASSA" quella a destra, word
  221.                ( "ALTA" quella a sinistra: $ALTABASS (.l = 4 bytes)
  222.  
  223.  move.w    #$123,d0    ; in questo caso cambiamo solo la word BASSA di d0,
  224.              ; se per esempio d0 era: $0012fe3c, agendo solo sulla
  225.              ; word bassa, ossia $fe3c, cambieremo d0 in $00120123.
  226.  
  227.  move.w    d1,d0        ; Allo stesso modo, copiamo la word "bassa" di d1 nella
  228.              ; word bassa di d0: se d1 contiene $12345678, mentre
  229.              ; d0 contiene $9abcdef0, dopo questa istruzione d0
  230.              ; conterra':  $9abc5678
  231.             ;                  ^^^^ WORD!
  232.  
  233. ; Registri dati, .b (byte)
  234.  
  235.  move.b    #$12,d0        ; in questo caso cambiamo solo il byte piu' a destra,
  236.              ; se per esempio d0 era: $0012fe3c, agendo solo sul
  237.              ; primo byte, ossia $3c, cambieremo d0 in $0012fe12.
  238.  
  239.  move.b    d1,d0        ; Allo stesso modo, copiamo il primo byte di d1 nel
  240.              ; primo di d0: se d1 contiene $12345678, mentre
  241.              ; d0 contiene $9abcdef0, dopo questa istruzione d0
  242.              ; conterra':  $9abcde78
  243.             ;                    ^^ BYTE!
  244.  
  245. I registri indirizzi a0,a1,a2,a3,a4,a5,a6 (NON USATE a7, detto SP: e' lo STACK)
  246. si comportano come i registri dati, ma non ci si puo' accedere col .b.
  247. Si possono usare anche per metterci dati, nonostante siano dedicati agli
  248. indirizzi.
  249.  
  250. **    **    **    **    **    **    **    **    **    **    **
  251.  
  252. ; INDIRIZZAMENTI INDIRETTI TRAMITE REGISTRI INDIRIZZO
  253.  
  254.  move.w #123,(a0)    ; In questo caso il numero 123 viene copiato nella word
  255.              ; contenuta nell'indirizzo che e' in a0. Si dice
  256.              ; indiretto perche' anziche' indicare l'indirizzo
  257.              ; vero e proprio si usa un registro che contiene
  258.              ; quell'indirizzo e tramite quell'indirizzo si indica
  259.              ; la destinazione. Questo avviene solo quando il
  260.              ; registro indirizzo e' tra parentesi, altrimenti
  261.              ; si metterebbe 123 proprio nel registro.
  262.              ; NON SI PUO' USARE UN REGISTRO DATI per
  263.              ; l'indirizzamento indiretto.
  264.             ; Si puo' dire che il registro a0 e' usato come
  265.             ; PUNTATORE a una locazione di memoria, cioe' PUNTA
  266.             ; come la freccia del mouse o un cane da caccia nella
  267.             ; direzione della preda: si dice "PUNTATORE"
  268.             ; un indirizzo o un registro in cui e' contenuto
  269.             ; l'indirizzo di qualcosa a cui si accede "chiedendo"
  270.             ; al puntatore dove si trovi. Per esempio la copperlist
  271.             ; ha un suo registro PUNTATORE, il $dff080, in cui
  272.             ; viene messo l'indirizzo della copperlist: il copper
  273.             ; ogni fotogramma video vede dov'e' la copperlist
  274.             ; dall'indirizzo contenuto in $dff080.
  275.  
  276.  move.l    (a0),(a1)    ; In questo caso copiamo la long contenuta in (a0),
  277.              ; ossia dall'indirizzo contenuto in a0, nella long
  278.              ; contenuta a partire dall'indirizzo in a1. Se prima
  279.              ; di eseguire questa istruzione in a0 ci fosse stato
  280.              ; l'indirizzo $100 e in a1 $200, la copia sarebbe
  281.              ; avvenuta come per un MOVE.L $100,$200, o per essere
  282.              ; piu' raffinati, MOVE.L $100.w,$200.w....
  283.  
  284.             -    -    -
  285.  
  286. ; INDIRIZZAMENTI INDIRETTI CON POST-INCREMENTO (indirizzo incrementato DOPO!)
  287.  
  288.  
  289.  move.w #123,(a0)+    ; In questo caso il numero 123 viene copiato nella word
  290.              ; contenuta nell'indirizzo che e' in a0, DOPODICHE'
  291.              ; A0 Viene INCREMENTATO di una WORD. Se l'istruzione
  292.              ; fosse stata .B, DOPO IL MOVE a0 sarebbe stato
  293.              ; incrementato di un byte, se fosse stata .L, sarebbe
  294.              ; stato incrementato di 4 bytes, cioe' una LONGWORD.
  295.  
  296.  move.l    (a0)+,(a1)+    ; In questo caso copiamo la long contenuta in (a0),
  297.              ; ossia dall'indirizzo contenuto in a0, nella long
  298.              ; contenuta a partire dall'indirizzo in a1, dopodiche'
  299.              ; aumentiamo di 4 , ossia di una long, sia a0 che
  300.              ; a1, in pratica spostiamo i due registri alla long
  301.              ; successiva. Con una serie di queste struzioni per
  302.              ; esempio si potrebbe copiare un pezzo di memoria:
  303.  
  304.     lea    $50000,a0    ; indirizzo sorgente
  305.     lea    $60000,a1    ; indirizzo destinazione
  306.     move.l    (a0)+,(a1)+
  307.     move.l    (a0)+,(a1)+
  308.     move.l    (a0)+,(a1)+
  309.     move.l    (a0)+,(a1)+
  310.     move.l    (a0)+,(a1)+
  311.  
  312.             ; In questo caso abbiamo copiato 5 longwords da
  313.             ; $50000 a $60000.
  314.  
  315.             -    -    -
  316.  
  317. ; INDIRIZZAMENTI INDIRETTI CON PRE-DECREMENTO (indirizzo decrementato PRIMA!)
  318.  
  319.  move.w #123,-(a0)    ; COME PRIMA COSA, A0 viene DECREMENTATO di 2, ossia
  320.              ; di una WORD (PRE-decremento), poi il numero 123 viene
  321.              ; copiato nella word contenuta nell'indirizzo che e'
  322.              ; in a0 (ossia quello a cui e' stato sottratto 2).
  323.              ; Se l'istruzione fosse stata .B, a0 sarebbe stato
  324.              ; decrementato di un byte, se fosse stata .L, sarebbe
  325.              ; stato decrementato di 4 bytes, cioe' una LONGWORD.
  326.  
  327.  move.l    -(a0),-(a1)    ; Vengono decrementati a0 ed a1 di 4 (una long),
  328.              ; poi viene copiata la long contenuta in (a0),
  329.              ; ossia dall'indirizzo contenuto in a0, nella long
  330.              ; contenuta a partire dall'indirizzo in a1.
  331.  
  332.              ; Con una serie di queste struzioni si potrebbe copiare
  333.              ; un pezzo di memoria come nel caso precedente, ma
  334.              ; procedendo "all'indietro" come i gamberi, infatti
  335.              ; bisogna partire dall'indirizzo dove finisce la copia
  336.              ; per tornare indietro fino agli indirizzi di inizio
  337.              ; della copia, ossia $50000 e $60000. Poniamo come
  338.              ; inizio dunque $50014 e $60014, poi copiamo una long
  339.              ; alla volta "all'indietro" fino alla locazione $50000
  340.              ; e $60000: per "calcolare" l'indirizzo da cui partire
  341.              ; ho aggiunto (5*4) ossia $14 agli indirizzi, ossia
  342.              ; 5 longwords * 4 bytes ogni longword. Da notare che
  343.              ; in memoria $50000+(5*4) viene assemblato come
  344.              ; $50014, infatti durante l'assemblaggio vengono anche
  345.              ; eseguite le eventuali operazioni matematiche.
  346.  
  347.     lea    $50000+(5*4),a0    ; indirizzo sorgente FINALE
  348.     lea    $60000+(5*4),a1    ; indirizzo destinazione FINALE
  349.     move.l    -(a0),-(a1)
  350.     move.l    -(a0),-(a1)
  351.     move.l    -(a0),-(a1)
  352.     move.l    -(a0),-(a1)
  353.     move.l    -(a0),-(a1)
  354.  
  355.             ; In questo caso abbiamo copiato 5 longwords da
  356.             ; $50000 a $60000, ma partendo da $50014 all'indietro
  357.             ; fino a $50000: La differenza con l'esempio precedente
  358.             ; e' come la differenza che c'e' tra iniziare a pulire
  359.             ; un corridoio da destra o da sinistra: in ambedue i
  360.             ; casi "copiamo" lo sporco nel cestino, ma facendo
  361.             ; il percorso in due sensi opposti.
  362.  
  363.             -    -    -
  364.  
  365. ; INDIRIZZAMENTI INDIRETTI CON DISTANZA DI INDIRIZZAMENTO (detto OFFSET)
  366.  
  367.  move.w #123,$34(a0)    ; In questo caso il numero 123 viene copiato nella word
  368.              ; contenuta nell'indirizzo ricavabile dalla somma di
  369.              ; quello in a0 + $34, ossia l'OFFSET. Se per esempio
  370.              ; in a0 ci fosse stato $50000, la word 123 sarebbe
  371.              ; stata copiata in $50034. L'Offset puo' variare tra
  372.              ; -32768 e 32767.
  373.  
  374.             -    -    -
  375.  
  376.  ; INDIRIZZAMENTI INDIRETTI CON DISTANZA DI INDIRIZZAMENTO E INDICE
  377.  
  378.  
  379.  move.w #12,5(a0,d0.w)    ; In questo caso il numero 12 viene copiato nella word
  380.              ; contenuta nell'indirizzo ricavabile dalla somma di
  381.              ; quello in a0 + 5, + la word in d0. Se per esempio
  382.              ; in a0 ci fosse stato $50000, in d0 $1000, la word 12
  383.              ; sarebbe stata copiata in $51005. L'Offset in questo
  384.              ; caso puo' variare tra -128 e +127 solamente.
  385.             ; In pratica viene aggiunto alla somma per ottenere
  386.             ; l'indirizzo finale anche un registro, che puo' essere
  387.             ; sia DATI che INDIRIZZI, di cui puo' essere usato
  388.             ; sia l'intero contenuto (d0.l) sia una word (d0.w),
  389.             ; ma non puo' essere considerato un byte solamente.
  390.             ; Si dice INDICE il registro aggiuntivo nella parentesi
  391.  
  392.         ALCUNI ESEMPI:
  393.  
  394.     lea    $50000,a3
  395.     move.w    #$6000,d2
  396.     move.l    #123,$30(a3,d2.w)    ; 123 copiato in $56030
  397. *
  398.     lea    $33000,a1
  399.     move.w    #$2000,a2
  400.     move.l    #123,$10(a1,a2.w)    ; 123 copiato in $35010
  401. *
  402.     lea    $33000,a1
  403.     lea    $20010,a2
  404.     move.l    #123,-$10(a1,a2.l)    ; 123 copiato in $53000
  405.  
  406. **    **    **    **    **    **    **    **    **    **    **
  407.  
  408.  ; INDIRIZZAMENTI RELATIVI AL PC (con offset automatico)
  409.  
  410. Questo tipo di indirizzamenti sono "sistemati" automaticamente dall'ASMONE e
  411. passano "INOSSERVATI": per esempio notate la differenza tra queste istruzioni:
  412.  
  413.     MOVE.L    LABEL1,d0        ; INDIRIZZO ASSOLUTI
  414.     MOVE.L    LABEL1(PC),d0        ; INDIRIZZO RELATIVO AL PC
  415.  
  416. Queste due istruzioni fanno la stessa cosa, ma quella col (PC) e' piu' corta
  417. e veloce della prima, ed e' RELATIVA AL PC, infatti si basa su una DISTANZA DI
  418. INDIRIZZAMENTO (offset) dal registro PC, ossia il PROGRAM COUNTER, che e' il
  419. registro dove il 68000 tiene l'indirizzo dove sta eseguendo attualmente.
  420. L'offset tra l'istruzione col (PC) e la label viene calcolata automaticamente
  421. dall'assemblatore in fase di assemblaggio, ed in memoria viene messo l'offset
  422. giusto per riferirsi alla label in questione spostandosi avanti o indietro
  423. dall'istruzione in esecuzione dei byte giusti, per cui l'istruzione non
  424. contiene l'indirizzo della label, ma il numero di byte in avanti o indietro
  425. che il processore deve fare per trovare la label in questione. La differenza
  426. e' evidente: se spostiamo tutto il codice in un'altra parte della memoria
  427. la distanza tra l'istruzione col (PC) e la label rimane la stessa, per cui
  428. l'istruzione "funziona" sempre, mentre se non e' relativa al PC, basta spostare
  429. il programma in un'altra parte della memoria per mandarlo in tilt: infatti
  430. il move.l LABEL1,d0 viene tradotto in MOVE.L $23000,d0 (per ipotesi), dunque
  431. la LABEL1 si trova a $23000. Se spostiamo tutto il programma (che per esempio
  432. partiva da $20000 e finiva a $25000) avanti di $10000, eseguendolo ci saranno
  433. problemi non indifferenti, in quanto il MOVE.L $23000,d0 non si riferira'
  434. piu' alla label1, che sara' ora in $33000!!!! Mentre se il codice era tutto
  435. Relativo al PC, il move si sarebbe sempre riferito alla label1, cioe' a
  436. $33000, calcolando la distanza tra il move e la label che si sarebbe mantenuta
  437. uguale. Anche le istruzioni come BRA, BSR, BNE, BEQ sono relative al PC, cioe'
  438. un BSR.W ROUTINE1 sara' assemblato in memoria come BSR (50 bytes piu' avanti),
  439. per esempio, e non BSR $30000. L'indirizzo viene assemblato da istruzioni
  440. equivalenti al BSR, come JSR: un JSR LABEL1 viene assemblato con l'indirizzo
  441. di LABEL1, allo stesso modo un JMP (SALTA-Equivalente al BRA) sara' assemblato
  442. con l'indirizzo REALE della label. Ma allora come mai non sono usati sempre
  443. move relativi al PC e BSR anziche' JSR?? Perche' gli indirizzamenti relativi
  444. al PC hanno la limitazione di potersi riferire a indirizzi distanti al massimo
  445. 32767 in avanti o -32768 indietro; per le label piu' distanti e' necessario
  446. usare move con indirizzi assoluti o JSR/JMP. Comunque come gia' detto  tutti
  447. questi calcoli sono fatti automaticamente dall'assemblatore, per cui non ci
  448. interessano, in pratica basta sapere che QUANDO SI PUO', e' sempre bene mettere
  449. un (PC) dopo la prima label e usare bsr/bra anziche' JSR/JMP; quando non e'
  450. possibile perche' la distanza e' maggiore di 32768 l'assemblatore comunica
  451. l'errore e basta togliere il (PC) o sostituire il BRA/BSR con un JMP/JSR, che
  452. possa raggiungere la massima distanza. Si potrebbe anche programmare con tutti
  453. JSR/JMP e move senza (PC), ma il codice risulterebbe piu' lungo e leggermente
  454. piu' lento, dunque e' sempre meglio tentare di fare al meglio!!!
  455. Il discorso della RILOCAZIONE, ossia dello spostamento delle routines in zone
  456. diverse della memoria, viene svolto dal sistema operativo: quando salviamo
  457. il nostro programma come eseguibile col comando "WO", salviamo un file che
  458. possiamo caricare dallo SHELL scrivendo il suo nome: il sistema operativo si
  459. occupa di mettere in un punto della memoria libera, che puo' essere uno
  460. qualsiasi, e RILOCA IL PROGRAMMA, ossia cambia anche gli indirizzi ai JSR e ai
  461. move non relativi al PC per farli tornare, quindi si puo' programmare senza
  462. farsi alcun problema di mettere tutti move (PC); Tra l'altro non e' possibile
  463. usare l'indirizzamento (PC) per label che si trovano in SECTION diverse del
  464. programma: per esempio le COPPERLIST se si trovano in una SECTION a se non
  465. possono essere modificate che con indirizzamenti senza (PC), perche' il sistema
  466. operativo "ALLOCA" le section a distanze imprevedibili, magari maggiori di
  467. 32768, del limite cioe' dell'indirizzamentp PC RELATIVE.
  468.  
  469.  
  470.     ESEMPI DI USO DELL'INDIRIZZAMENTO RELATIVO AL PC:
  471.  
  472.     MOVE.L    LABEL1(PC),LABEL2    ; Nota: non si puo' mettere il (PC)
  473.                     ; alle label usate come destinazione!
  474.                     ; move.l a0,LABEL(PC) e' un ERRORE!
  475.     ADD.L    LABELBAU(PC),d0        ; Si puo' perche' la label e' SORGENTE
  476.     SUB.L    #500,LABEL        ; NON SI PUO' METTERE IL PC, perche'
  477.                     ; la label qua e' DESTINAZIONE
  478.     CLR.L    LABEL            ; non si puo' mettere il PC in questo
  479.                     ; caso; in pratica il (PC) si puo'
  480.                     ; solo mettere quando la label e'
  481.                     ; prima della virgola!
  482.  
  483.  ; INDIRIZZAMENTI RELATIVI AL PC CON OFFSET E INDICE
  484.  
  485. Questo indirizzamento e' lo stesso di prima, con l'INDICE, ossia con un
  486. registro che va sommato al (PC) e all'OFFSET, proprio come avviene per
  487. l'offset+indice dei registri INDIRIZZI:
  488.  
  489.  
  490.     MOVE.L    LABEL1(PC,d0.w),LABEL2    ; come l'indirizzamento (PC),ma in piu'
  491.                     ; si deve aggiungere al conto la word
  492.                     ; contenuta in d0, dunque non ci si
  493.                     ; riferisce a LABEL1, ma a qualche
  494.                     ; label a distanza D0 da LABEL1
  495.     ADD.L    LABELBAU(PC,a0.l),d0    ; Come prima, usando A0.L come indice.
  496.  
  497. Questo e' tutto per quanto riguarda gli indirizzamenti.
  498.  
  499. **    **    **    **    **    **    **    **    **    **    **
  500.  
  501. ISTRUZIONI PIU' COMUNI:
  502.  
  503.     MOVE.x    SORGENTE,DESTINAZIONE    ; Copia un byte, una word o una
  504.                     ; longword
  505.  
  506.     LEA    indirizzo,Ax        ; Carica un indirizzo: Questa
  507.                     ; istruzione puo' essere usata solo
  508.                     ; con i registri indirizzi e serve
  509.                     ; a mettere l'indirizzo in questione
  510.                     ; nel registro (sia esso sotto forma
  511.                     ; di label o di numero es. $50000).
  512.                     ; E' equivalente ad un:
  513.                     ; MOVE.L #indirizzo,a0
  514.                     ; ma e' piu' veloce.
  515.  
  516.  
  517.     CLR.x    destinazione        ; Questo comando AZZERA la destinazione
  518.                     ; CLR=CLEAR=PULISCI
  519.  
  520.  
  521. SALTI CONDIZIONATI DA UN TST,BTST,CMP
  522.  
  523.     CMP.x    sorgente,destinazione    ; COMPARA 2 operandi, che possono
  524.                     ; essere una label e un registro, o
  525.                     ; un numero assoluto # e un registro
  526.                     ; o altro ancora. L'esito POSITIVO e'
  527.                     ; dato se i 2 operandi sono UGUALI
  528.                     ; per il BEQ/BNE seguenti
  529.  
  530.     TST.x    registro.label/indir.    ; Controlla se l'operando in questione
  531.                     ; e' uguale a ZERO, se si da' ESITO
  532.                     ; POSITIVO
  533.  
  534.     BTST    #x,indirizzo/Dx        ; Controlla se il bit x dell'indirizzo
  535.                     ; e' a ZERO; se si ESITO POSITIVO;
  536.                     ; si puo' eseguire un BTST anche su
  537.                     ; un indirizzo dati, in questo caso
  538.                     ; si puo' fare il test su uno dei
  539.                     ; 32 bit possibili (0-31), altrimenti
  540.                     ; se il btst e' su una locazione di
  541.                     ; memoria si puo' fare il test su
  542.                     ; un byte solamente (bits 0-7).
  543.  
  544. Subito dopo un CMP, un TST o un BTST c'e' sempre un BNE, un BEQ o un altro
  545. comando simile. Nel caso del BNE e del BEQ si possono fare diramazioni e
  546. salti condizionati dal TST/CMP. I BEQ/BNE/BRA/BSR possono essere .w o .b,
  547. a seconda della distanza delle routine che indicano. Se sono vicinissime
  548. si puo' usare il .b (si usa anche il .s, ossia SHORT=CORTO).
  549.  
  550.  
  551.     BSR.x    label        ; Esegui la routine LABEL, dopodiche'
  552.                 ; ritorna avendo trovato RTS alla fine
  553.                 ; della routine "label"
  554.  
  555.     BEQ.x    label        ; Se l'esito e' positivo, salta a label
  556.                 ; (NON RITORNA PERO' DOPO AVER ESEGUITO
  557.                 ; LA LABEL COME UN BSR, QUA SCEGLIE SE
  558.                 ; SALTARE O NO
  559.  
  560.     BNE.x    label        ; Se l'esito non e' positivo, salta a label
  561.                 ; (NON RITORNA PERO' DOPO AVER ESEGUITO
  562.  
  563.     BRA.x    label        ; Salta SEMPRE a label (COME JMP)
  564.  
  565.  
  566.     ADD.x    operando1,destinazione    ; Con questa istruzione si aggiunge
  567.                     ; un valore alla destinazione
  568.  
  569.     SUB.x    operando1,destinazione    ; con questa istruzione si sottrae
  570.                     ; un valore alla destinazione
  571.  
  572.  
  573.     SWAP    Dx        ; Scambia le 2 words della longword
  574.                 ; contenuta in un registro DATI, non
  575.                 ; necessita di .b,.w o .l
  576.  
  577. lo SWAP, in inglese significa SCAMBIA, infatti SCAMBIA le 2 words di una
  578. longwords facendo diventare BASSA quella ALTA e viceversa:
  579.  
  580.     MOVE.L    #CANETOPO,d0    ; in d0 mettiamo la longword CANETOPO
  581.  
  582.     SWAP    d0        ; SCAMBIAMO LE WORDS: il risultato e' che
  583.                 ; in d0 abbiamo TOPOCANE!!!!
  584.  
  585.                 *
  586.  
  587. NOTA: Esistono delle istruzioni dedicate per i registri address: per
  588. esempio dovremmo scrivere CMPA.W d0,a0 e non CMP.W d0,a0, allo stesso
  589. modo dovremmo scrivere ADDA.W a2,a0 e non ADD.W a2,a0;
  590. invece per le COSTANTI (#xxxx) dovremmo usare CMPI.x #10,d0 e non CMP.x #1,d0,
  591. dovremmo scrivere SUBI.x #123,d2 e non SUB.x #123,d2, ma l'asmone ASSEMBLA
  592. AUTOMATICAMENTE L'ISTRUZIONE GIUSTA anche se scriviamo sempre cmp/add/sub
  593. eccetera con i registri indirizzo e nei casi di #xxx,operando. Dunque non
  594. occorre farsi problemi se in un listato compare a volte un cmpi e altre il
  595. cmp normale, o un adda e altre volte un add, perche' l'asmone assembla sempre
  596. bene. Per verificare provate ad assemblare queste linee e a disassemblarle
  597. con "D PROVA", l'ASMONE assemblera' secondo la regola.
  598.  
  599. PROVA:
  600.     CMP.W    d0,a0
  601.     ADD.W    a1,a2
  602.     SUB.L    #123,$10000
  603.     CMP.b    #20,d4
  604.  
  605. Sara' assemblato come:
  606.  
  607.     CMPA.W    D0,A0
  608.     ADDA.W    A1,A2
  609.     SUBI.L    #$0000007B,$00010000
  610.     CMPI.B    #$14,D4
  611.  
  612.  
  613.             -    -    -
  614.  
  615. NOTA2: Certe istruzioni che fanno la stessa cosa possono essere scritte in
  616. modo diverso: ad esempio il 68000 ha dei comandi dedicati a situazioni
  617. particolari che sono piu' veloci in quelle situazioni:
  618.  
  619. 1) ADDQ.x #Numero,destinazione    ; Il comando ADDQ.x puo' essere usato per
  620.                 ; le addizioni con numeri che siano da 1 a 8
  621.                 ; (Q sta per QUICK=VELOCE!)
  622.  
  623. 1) SUBQ.x #Numero,destinazione    ; Il comando SUBQ.x puo' essere usato per
  624.                 ; le sottrazioni con numeri che siano da 1 a 8
  625.  
  626. 3) MOVEQ #Numero,dx        ; Il comando MOVEQ si puo' usare per sostituire
  627.                 ; i MOVE.L #num,d0, in cui il num e' tra
  628.                 ; -128 e +127. Il MOVEQ e' sempre .L, dunque
  629.                 ; non necessita di .b,.w o .l
  630.  
  631.             -    -    -
  632.