Capítol 4: Tutorial del llenguatge ensamblador del microprocessador 6502

Capitol 4 Tutorial Del Llenguatge Ensamblador Del Microprocessador 6502



Capítol 4: Tutorial del llenguatge ensamblador del microprocessador 6502

4.1 Introducció

El microprocessador 6502 es va llançar el 1975. Es va utilitzar com a microprocessador per a alguns ordinadors personals aleshores com Apple II, Commodore 64 i BBC Micro.







El microprocessador 6502 encara s'està produint en gran quantitat avui dia. Ja no és una unitat central de processament que s'utilitza en ordinadors personals (ordinadors portàtils) avui en dia, però encara es produeix en gran quantitat i s'utilitza en aparells electrònics i elèctrics avui dia. Per tal d'entendre les arquitectures d'ordinadors més modernes, és molt útil examinar un microprocessador més antic però amb força èxit com el 6502.



Com que és senzill d'entendre i programar, és un dels millors (si no el millor) microprocessador per utilitzar per ensenyar llenguatge assemblador. El llenguatge ensamblador és un llenguatge de baix nivell que es pot utilitzar per programar un ordinador. Tingueu en compte que el llenguatge assemblador d'un microprocessador és diferent del llenguatge assemblador d'un altre microprocessador. En aquest capítol s'ensenya el llenguatge ensamblador del microprocessador 6502. Més precisament, és el 65C02 el que s'ensenya, però simplement es coneix com el 6502.



Un ordinador famós en el passat s'anomena commodore_64. El 6502 és un microprocessador de la família 6500. L'ordinador commodore_64 utilitza el microprocessador 6510. El microprocessador 6510 és de 6500 µP. El conjunt d'instruccions del 6502 µP és gairebé totes les instruccions del 6510 µP. El coneixement d'aquest capítol i el següent es basa en l'ordinador commodore_64. Aquests coneixements s'utilitzen com a bases per explicar les arquitectures informàtiques modernes i els sistemes operatius moderns en aquesta part del curs de carrera en línia.





L'arquitectura de l'ordinador fa referència als components de la placa base de l'ordinador i una explicació de com flueixen les dades dins de cada component, especialment el microprocessador, com flueixen les dades entre els components i també com les dades interaccionen. El singular de les dades és datum. Una manera eficaç d'estudiar l'arquitectura d'un ordinador és estudiar el llenguatge ensamblador de la placa base.

Es diu que l'ordinador commodore_64 és un ordinador de 8 bits. Això significa que la informació s'emmagatzema, es transfereix i es manipula en forma de codis binaris de vuit bits.



Diagrama de blocs de la placa base Commodore 64
El diagrama de blocs de la placa base Commodore 64 és:


Fig 4.1 Diagrama de blocs de la unitat del sistema Commodore_64

Imagineu el microprocessador 6510 com el microprocessador 6502. La memòria total és una sèrie de bytes (8 bits per byte). Hi ha la memòria d'accés aleatori (lectura/escriptura) a la qual es poden escriure o esborrar els bytes. Quan s'apaga l'ordinador, s'esborra tota la informació de la memòria d'accés aleatori (RAM). També hi ha la memòria de només lectura (ROM). Quan s'apaga l'ordinador, la informació de la ROM es manté (no s'esborra).

Hi ha el port d'entrada/sortida (circuit) que es coneix com a dispositius d'entrada/sortida al diagrama. Aquest port no s'ha de confondre amb els ports que són visibles a les superfícies verticals esquerra i dreta o frontal i posterior de la unitat del sistema informàtic. Són dues coses diferents. Les connexions d'aquest port interior als perifèrics com el disc dur (o disquet), el teclat i el monitor no es mostren al diagrama.

Hi ha tres busos (grups de conductors elèctrics molt petits) al diagrama. Cada cable pot transferir un bit 1 o un bit 0. El bus de dades, per a la transferència de octets de vuit bits a la vegada (un pols de rellotge) a la memòria RAM i al port d'entrada/sortida (dispositius d'entrada/sortida) és bidireccional. El bus de dades té vuit bits d'amplada.

Tots els components estan connectats al bus d'adreces. El bus d'adreces és unidireccional des del microprocessador. Hi ha setze conductors per al bus d'adreces, i cadascun porta un bit (1 o 0). S'envien setze bits en un pols de rellotge.

Hi ha el bus de control. Alguns dels conductors del bus de control transferirien un bit cadascun del microprocessador als altres components. Unes quantes línies de control porten els bits des del port d'entrada/sortida (IO) al microprocessador.

Memòria d'ordinador
La memòria RAM i la ROM es consideren com un conjunt de memòria. Aquest conjunt es representa esquemàticament de la manera següent, on els números hexadecimals tenen el prefix '$':


Fig 4.11 Disseny de memòria per a l'ordinador Commodore 64

La memòria RAM és de 0000 16 a DFFF 16 que s'escriu com de $0000 a $DFFF. Amb el llenguatge assemblador de 6502 µP, un número hexadecimal té el prefix '$' i no el sufix (subíndex) amb 16 o H o hex. Qualsevol informació de la memòria RAM s'apaga quan l'ordinador està apagat. La ROM comença des de $E000 fins a $FFFF. Té subrutines que no s'apaguen quan l'ordinador està apagat. Aquestes subrutines són les rutines d'ús habitual que ajuden a la programació. El programa d'usuari els crida (consulteu el capítol següent).

L'espai (bytes) de $0200 a $D000 és per als programes d'usuari. L'espai de $D000 a $DFFF és per a la informació que està directament relacionada amb els perifèrics (dispositius d'entrada/sortida). Això forma part del sistema operatiu. Per tant, el sistema operatiu de l'ordinador commodore-64 consta de dues parts principals: la part de la ROM que mai s'apaga i la part de $D000 a $DFFF que s'apaga quan s'apaga l'alimentació. Aquestes dades d'IO (entrada/sortida) s'han de carregar des d'un disc cada vegada que l'ordinador s'encén. Avui, aquestes dades s'anomenen controladors perifèrics. Els perifèrics comencen des del port del dispositiu d'entrada/sortida a través de les connexions de la placa base fins als ports identificables de les superfícies verticals de l'ordinador al qual es connecten el monitor, teclat, etc. i als propis perifèrics (monitor, teclat, etc.). .).

La memòria consta de 2 16 = ubicacions de 65.536 bytes. En forma hexadecimal, són 10000 16 = 10000 H = 10000 hexadecimal = ubicacions de 10.000 $. En informàtica, comptar en base dos, base deu, base setze, etc. comença des de 0 i no des de 1. Per tant, la primera ubicació és en realitat el número d'ubicació de 0000000000000000. 2 = 0 10 = 0000 16 = 0000 $. En el llenguatge assemblador 6502 µP, la identificació d'una ubicació d'adreça té el prefix $ i no hi ha sufix ni subíndex. L'última ubicació és el número d'ubicació 1111111111111111 2 = 65,535 10 = FFFF 16 = $FFFF i no 10000000000000000 2 , o 65.536 10 , o 10.000 16 , o 10.000 dòlars. El 10000000000000000 2 , 65,536 10 , 10000 16 , o $10000 proporciona el nombre total d'ubicacions de bytes.

Aquí, 2 16 = 65.536 = 64 x 1024 = 64 x 2 10 = 64 kbytes (kilobytes). El sufix de 64 en el nom Commodore-64 significa 64KB de memòria total (RAM i ROM). Un byte és de 8 bits i els 8 bits aniran a la ubicació d'un byte a la memòria.

Els 64 Kbytes de memòria es divideixen en pàgines. Cada pàgina té 0100 16 = 256 10 ubicacions de bytes. Els primers 256 10 = primer 0100 16 ubicacions és la pàgina 0. El segon és la pàgina 1, el tercer és la pàgina 2, i així successivament.

Per adreçar les 65.536 ubicacions, calen 16 bits per a cada ubicació (adreça). Així, el bus d'adreces del microprocessador a la memòria consta de 16 línies; una línia per un bit. Un bit és 1 o 0.

Els registres 6502 µP
Un registre és com les cel·les de bytes per a una ubicació de memòria de bytes. El 6502 µP té sis registres: cinc registres de 8 bits i un registre de 16 bits. El registre de 16 bits s'anomena comptador de programes que s'abreuja com a PC. Conté l'adreça de memòria per a la següent instrucció. Un programa de llenguatge assemblador consta d'instruccions que es col·loquen a la memòria. Es necessiten setze (16) bits diferents per adreçar una ubicació de bytes concreta a la memòria. A un pols de rellotge particular, aquests bits s'envien a les línies d'adreces de 16 bits del bus d'adreces per a la lectura d'una instrucció. Tots els registres del 6502 µP es representen de la següent manera:


Fig. 4.12 Registres de 6502 µP

El comptador de programes o PC es pot veure com un registre de 16 bits al diagrama. Els vuit bits significatius més baixos s'etiqueten com a PCL per a Program Counter Low. Els vuit bits més significatius s'etiqueten com a PCH per a Program Counter High. Una instrucció a la memòria per al Commodore-64 pot consistir en un, dos o tres bytes. Els 16 bits del PC apunten a la següent instrucció a executar, a la memòria. Entre els circuits del microprocessador, dos d'ells s'anomenen Unitat lògica aritmètica i Decodificador d'instruccions. Si la instrucció actual que s'està processant al µP (microprocessador) té un byte de llarg, aquests dos circuits augmenten el PC per a la següent instrucció en 1 unitat. Si la instrucció actual que s'està processant al µP té dos bytes de llarg, és a dir, ocupa dos bytes consecutius a la memòria, aquests dos circuits augmenten el PC per a la següent instrucció en 2 unitats. Si la instrucció actual que s'està processant al µP té tres bytes de llarg, és a dir, ocupa tres bytes consecutius en memòria, aquests dos circuits augmenten el PC per a la següent instrucció en 3 unitats.

L'acumulador 'A' és un registre de propòsit general de vuit bits que emmagatzema el resultat de la majoria d'operacions aritmètiques i lògiques.

Els registres 'X' i 'Y' s'utilitzen cadascun per comptar els passos del programa. El recompte en la programació comença a partir de 0. Per tant, s'anomenen registres d'índex. Tenen uns quants altres propòsits.

Tot i que el registre Stack Pointer, 'S' té 9 bits que es considera un registre de vuit bits. El seu contingut apunta a una ubicació de bytes a la pàgina 1 de la memòria d'accés aleatori (RAM). La pàgina 1 comença amb el byte $0100 (256 10 ) al byte $01FF (511 10 ). Quan un programa s'està executant, es mou d'una instrucció a la següent instrucció consecutiva de la memòria. Tanmateix, no sempre és així. Hi ha moments en què salta d'una àrea de memòria a una altra àrea de memòria per continuar executant-hi les instruccions, de manera consecutiva. La pàgina 1 a la memòria RAM s'utilitza com a pila. La pila és una gran àrea de memòria RAM que té les següents adreces per a la continuació del codi des d'on hi ha un salt. Els codis amb instruccions de salt no estan a la pila; estan en un altre lloc de la memòria. Tanmateix, després d'executar les instruccions de salt a, les adreces de continuació (no els segments de codi) es troben a la pila. Van ser empès allà com a conseqüència de les instruccions de salt o branca.

El registre d'estat del processador de vuit bits de P és un tipus especial de registre. Els bits individuals no estan relacionats ni connectats entre si. Cada bit allà s'anomena bandera i s'aprecia independentment dels altres. Els significats de les banderes es donen a continuació a mesura que sorgeix la necessitat.

El primer i l'últim índex de bit per a cada registre s'indiquen a sobre de cada registre al diagrama anterior. L'índex de bits (posició) que compta en un registre comença des de 0 a la dreta.

Pàgines de memòria en binari, hexadecimal i decimal
La taula següent mostra l'inici de les pàgines de memòria en binari, hexadecimal i decimal:

Cada pàgina en té 1.0000.0000 2 nombre de bytes que és el mateix que 100 H nombre de bytes que és el mateix que 256 10 nombre de bytes. En el diagrama de memòria anterior, les pàgines s'indiquen pujant des de la pàgina 0 i no baixant com s'indica a la taula.

Les columnes binàries, hexadecimals i decimals d'aquesta taula proporcionen les adreces d'ubicació dels bytes de memòria en les seves diferents bases. Tingueu en compte que per a la pàgina zero, només cal escriure els bits del byte inferior quan es codifiquen. Els bits del byte superior es poden ometre ja que sempre són zeros (per a la pàgina zero). Per a la resta de pàgines, s'han d'utilitzar els bits del byte més alt.

La resta d'aquest capítol explica el llenguatge assemblador 6502 µP utilitzant tota la informació anterior. Per entendre ràpidament el llenguatge, el lector ha de sumar i restar en base setze en lloc de base deu. En realitat se suposa que és la base dos, però calcular a la base dos és complicat. Recordeu que quan sumeu dos nombres en base dos, un acarreament continua sent 1 com en la base deu. Però en restar dos nombres a la base dos, un préstec és dos i no deu com en la base deu. Quan s'afegeixen dos nombres en la base setze, un acarreament continua sent 1 com en la base deu. Però en restar dos nombres de la base setze, un préstec és setze i no deu com en la base deu.

4.2 Instruccions de transferència de dades

Considereu la taula següent de les instruccions de transferència de dades en llenguatge ensamblador per al 6502 µP:

Quan es copia un byte (8 bits) des d'una ubicació de bytes de memòria al registre d'acumulador, al registre X o al registre Y, s'està carregant. Quan es copia un byte de qualsevol d'aquests registres a una ubicació de bytes de memòria, s'està transferint. Quan es copia un byte d'un registre a un altre, encara s'està transferint. A la segona columna de la taula, la fletxa mostra la direcció de la còpia per a un byte. La resta de les quatre columnes mostren diferents modes d'adreçament.

Una entrada a la columna del mode d'adreçament és el codi de bytes real de la part mnemotècnica corresponent de la instrucció en hexadecimal. AE, per exemple, és el codi de bytes real per a LDX que és carregar un byte de la memòria al registre X en mode d'adreçament absolut com AE 16 = 10101110 2 . Per tant, els bits per a LDX en una ubicació de bytes de memòria són 10101110.

Observeu que per a la part mnemotècnica LDX de la instrucció, hi ha tres bytes possibles que són A2, AE i A6, i cadascun és per a un mode d'adreçament particular. Quan el byte que es carrega al registre X no s'ha de copiar des d'una ubicació de bytes de memòria, el valor s'ha d'escriure amb (just després) el mnemotècnic LDX a la instrucció en hexadecimal o decimal. En aquest capítol, aquests valors s'escriuen en hexadecimal. Aquest és un adreçament immediat, de manera que el byte real a la memòria per representar LDX és A2 16 = 10100010 2 i no AE 16 que és igual a 10101110 2 .

A la taula, tots els bytes dels encapçalaments del mode d'adreçament s'anomenen Codis d'operació, que s'abreuja com a codis operatius. Hi pot haver més d'un codi operatiu per a un mnemotècnic, depenent del mode d'adreçament.

Nota: La paraula 'càrrega' a la unitat del sistema informàtic pot tenir dos significats: pot referir-se a la càrrega d'un fitxer des d'un disc a la memòria de l'ordinador o pot referir-se a la transferència d'un byte des d'una ubicació de bytes de memòria a un registre de microprocessador. .

Hi ha més modes d'adreçament que els quatre de la taula per al 6502 µP.

Tret que s'indiqui el contrari, tot el codi de programació d'usuari d'aquest capítol comença des de l'adreça 0200 16 que és l'inici de l'àrea d'usuari a la memòria.

Memòria M i acumulador A

Memòria a acumulador

Adreçament Immediat
La següent instrucció emmagatzema el número FF 16 = 255 10 a l'acumulador:

LDA #$FF

El '$' no només s'utilitza per identificar una adreça de memòria. En general, s'utilitza per indicar que el número següent que segueix és hexadecimal. En aquest cas, $FF no és l'adreça de cap ubicació de bytes de memòria. És el número 255 10 en hexadecimal. La base 16 o qualsevol dels seus altres subíndexs equivalents no s'han d'escriure a la instrucció de la llengua ensambladora. El '#' indica que el que segueix a continuació és el valor que s'ha de posar al registre de l'acumulador. El valor també es pot escriure en base deu, però això no es fa en aquest capítol. El '#' significa adreçament immediat.

Un mnemotècnic té certa semblança amb la seva frase en anglès corresponent. 'LDA #$FF' significa carregar el número 255 10 a l'acumulador A. Com que es tracta d'un adreçament immediat de la taula anterior, LDA és A9 i no AD o A5. A9 en binari és 101010001. Per tant, si A9 per a LDA es troba a l'adreça $0200 a la memòria, $FF és a $0301 = 0300 + 1 adreça. El #$FF és precisament l'operand per a la mnemotècnica LDA.

Adreçament absolut
Si el valor de $FF es troba a la ubicació $0333 de la memòria, la instrucció anterior és:

LDA $ 0333

Tingueu en compte l'absència de #. En aquest cas, l'absència de # significa que el que segueix és una adreça de memòria i no el valor d'interès (no el valor a posar a l'acumulador). Per tant, el codi operatiu per a LDA, aquesta vegada, és AD i no A9 o A5. L'operand per a LDA aquí és l'adreça $0333 i no el valor $FF. $FF es troba a una ubicació de $0333, que és bastant llunyana. La instrucció 'LDA $0333' ocupa tres ubicacions consecutives a la memòria, i no dues, com feia la il·lustració anterior. 'AD' per a LDA es troba a la ubicació de $ 0200. El byte inferior de 0333, que és 33, es troba a la ubicació $0301. El byte més alt de $0333, que és 03, es troba a la ubicació $0302. Aquesta és poca endianitat que s'utilitza pel llenguatge assemblador 6502. Els llenguatges assembladors dels diferents microprocessadors són diferents.

Aquest és un exemple d'adreçament absolut. El $0333 és l'adreça de la ubicació que té $FF. La instrucció consta de tres bytes consecutius i no inclou el $FF ni la seva ubicació real del byte.

Adreçament de pàgines zero

Suposem que el valor $FF es troba a la ubicació de memòria $0050 a la pàgina zero. Les ubicacions dels bytes per a la pàgina zero comencen a partir de $ 0000 i acaben a $ 00FF. Aquests són 256 10 ubicacions en total. Cada pàgina de la memòria Commodore-64 és 256 10 llarg. Tingueu en compte que el byte més alt és zero per a totes les ubicacions possibles a l'espai de pàgina zero a la memòria. El mode d'adreçament de pàgina zero és el mateix que el mode d'adreçament absolut, però el byte més alt de 00 no s'escriu a la instrucció. Per tant, per carregar el $FF des de la ubicació $0050 a l'acumulador, la instrucció del mode d'adreçament de pàgina zero és:

LDA $ 50

Amb LDA A5 i no A9 o AD, A5 16 = 10100101 2 . Recordeu que cada byte de la memòria és de 8 cel·les, i cada cel·la alberga una mica. La instrucció aquí consta de dos bytes consecutius. A5 per a LDA es troba a la ubicació de memòria de $ 0200 i l'adreça de $ 50, sense el byte més alt de 00, es troba a la ubicació de $ 0301. L'absència de 00, que hauria consumit un byte en la memòria total de 64K, estalvia l'espai de memòria.

Acumulador a la memòria

Adreçament absolut
La següent instrucció copia un valor de byte, sigui quin sigui, de l'acumulador a la ubicació de memòria de $1444:

SÓN 1444 $

Es diu que això es transfereix de l'acumulador a la memòria. No s'està carregant. La càrrega és el contrari. El byte del codi operatiu per a STA és 8D 16 = 10001101 2 . Aquesta instrucció consta de tres bytes consecutius a la memòria. El 8D 16 es troba a la ubicació de $ 0200. El 44 16 de l'adreça de $1444 es troba a la ubicació $0201. I 14 16 es troba a la ubicació de $ 0202 - Little Endianness. El byte real que es copia no forma part de la instrucció. 8D i no 85 per a l'adreçament de pàgina zero (a la taula) s'utilitzen aquí per a STA.

Adreçament de pàgines zero
La instrucció següent copia un valor de byte, sigui quin sigui, de l'acumulador a la ubicació de memòria de $0050 a la pàgina zero:

STA $ 0050

El byte del codi operatiu per a STA aquí és 85 16 = 10000101 2 . Aquesta instrucció consta de dos bytes consecutius a la memòria. El 85 16 es troba a 0200 $. Els 50 16 de l'adreça $0050 es troba a la ubicació $0201. El problema de l'endianness no sorgeix aquí perquè l'adreça només té un byte que és el byte inferior. El byte real que es copia no forma part de la instrucció. 85 i no 8D per a l'adreçament de pàgina zero s'utilitzen aquí per a STA.

No té sentit utilitzar l'adreçament immediat per transferir un byte de l'acumulador a una ubicació de la memòria. Això es deu al fet que el valor real com $FF s'ha de citar a la instrucció d'adreçament immediat. Per tant, l'adreçament immediat no és possible per a la transferència d'un valor de byte des d'un registre del µP a cap ubicació de memòria.

Mnemotècnia LDX, STX, LDY i STY
LDX i STX són similars a LDA i STA, respectivament. Però aquí s'utilitza el registre X i no el registre A (acumulador). LDY i STY són similars a LDA i STA, respectivament. Però aquí s'utilitza el registre Y i no el registre A. Consulteu la Taula 4.21 per a cada codi operatiu en hexadecimal que correspon a una mnemotècnica concreta i a un mode d'adreçament concret.

Transferències de registre a registre
Els dos conjunts anteriors d'instruccions de la Taula 4.21 tracten la còpia de memòria/microprocessador-registre (transferència) i la còpia de registre/registre (transferència). Les instruccions TAX, TXA, TAY, TYA, TSX i TXS fan la còpia (transferència) del registre del microprocessador a un altre registre del mateix microprocessador.

Per copiar el byte de A a X, la instrucció és:

IMPOSTA

Per copiar el byte de X a A, la instrucció és:

TX

Per copiar el byte de A a Y, la instrucció és:

Per copiar el byte de Y a A, la instrucció és:

TYA

Per a l'ordinador Commodore 64, la pila és la pàgina 1 just després de la pàgina 0 a la memòria. Com totes les altres pàgines, consta de 25610 10 ubicacions de bytes, de $0100 a $01FF. Normalment, un programa s'executa d'una instrucció a la següent instrucció consecutiva a la memòria. De tant en tant, hi ha un salt a un altre segment de codi de memòria (conjunt d'instruccions). L'àrea de pila de la memòria (RAM) té les següents adreces d'instruccions des d'on es van deixar els salts (o les ramificacions) per a la continuació del programa.

El punter de pila 'S' és un registre de 9 bits a 6502 µP. El primer bit (el més a l'esquerra) és sempre 1. Totes les adreces d'ubicació de bytes de la pàgina 1 comencen amb 1 seguit de 8 bits diferents per als 256 10 ubicacions. El punter de pila té l'adreça de la ubicació a la pàgina 1 que té l'adreça de la següent instrucció que el programa ha de retornar i continuar després d'executar el segment de codi actual (saltat a). Com que el primer bit de totes les adreces de la pila (pàgina 1) comença amb 1, el registre del punter de pila només necessita contenir els vuit bits restants. Després de tot, el seu primer bit, que és el bit més esquerre (el novè bit comptant des de la seva dreta), sempre és 1.

Per copiar el byte de S a X, la instrucció és:

TSX

Per copiar el byte de X a S, la instrucció és:

TXT

Les instruccions de registre a registre no prenen cap operand. Consten només de la mnemotècnica. Cada mnemotècnica té el seu codi operatiu en hexadecimal. Això està en mode d'adreçament implícit perquè no hi ha cap operand (sense adreça de memòria, sense valor).

Nota: No hi ha transferència X a Y o Y a X (còpia).

4.3 Operacions aritmètiques

El circuit, unitat aritmètica lògica a 6502 µP, només pot afegir dos nombres de vuit bits alhora. No resta, no multiplica i no divideix. La taula següent mostra els codis operatius i els modes d'adreçament per a les operacions aritmètiques:

Nota: Totes les mnemotècniques per a operacions aritmètiques i altres tipus d'operacions (és a dir, totes les mnemotècniques 6502) prenen un byte de codi d'operació (op). Si hi ha més d'un mode d'adreçament per al mnemotècnic, hi hauria diferents operacions per al mateix mnemotècnic: un per mode d'adreçament. La C, D i V de la taula són les banderes del registre d'estat. Els seus significats es donaran més endavant a mesura que sorgeixi la necessitat.

Suma de números sense signar
Amb el 6502 µP, els nombres amb signe són números de complement a dos. Els nombres sense signe són nombres positius ordinaris que comencen per zero. Per tant, per a un byte de vuit bits, el nombre sense signe més petit és 00000000 2 = 0 10 = 00 16 i el número més gran sense signar és 11111111 2 = 255 10 = FF 16 . Per a dos nombres sense signe, la suma és:

A+M+C→A

Això vol dir que la unitat lògica aritmètica afegeix el contingut de 8 bits de l'acumulador a un byte (8 bits) de la memòria. Després de l'addició d'A i M, el transport al novè bit passa a la cel·la del senyal de transport del registre d'estat. Qualsevol bit de transport anterior d'una addició anterior que encara es troba a la cel·la del senyal de transport del registre d'estat també s'afegeix a la suma d'A i M, fent A+M+C→A. El resultat es torna a posar a l'acumulador.

Si l'afegit d'interès és:

A + M

I no cal afegir cap transport anterior, s'ha d'esborrar la bandera de transport que es fa 0, de manera que l'addició sigui:

A+M+0→A igual que A+M→A

Nota: Si s'afegeix M a A i es produeix una transferència d'1 perquè el resultat és superior a 255 10 = 11111111 2 = FF 16 , aquest és un nou transport. Aquest nou transport d'1 s'envia automàticament a la cel·la del senyal de transport en cas que ho necessiti el següent parell de vuit bits a sumar (un altre A + M).

Codi per afegir dos vuit bits sense signar
00111111 2 + 00010101 2 és el mateix que 3F 16 + 15 16 que és el mateix que 63 10 + 21 10 . El resultat és 010101002 2 que és el mateix que 54 16 i 84 10 . El resultat no supera el nombre màxim de vuit bits que és 255 10 = 11111111 2 = FF 16 . Per tant, no hi ha cap transport d'1. Per dir-ho d'una altra manera, el transport resultant és 0. Abans de l'addició, no hi ha cap transport anterior d'1. És a dir, el transport anterior és 0. El codi per fer aquesta suma. pot ser:

CLC
LDA#$3F
ADC #$15

Nota: Mentre s'escriu el llenguatge ensamblador, es prem la tecla 'Enter' del teclat al final de cada instrucció. Hi ha tres instruccions en aquest codi. La primera instrucció (CLC) esborra el senyal de transport en cas que una addició anterior tingui 1. CLC només es pot fer en mode d'adreçament implícit. La mnemotècnica del mode d'adreçament implícit no pren cap operand. Això esborra la cel·la de transport del registre d'estat de P. Esborrar significa donar el bit de 0 a la cel·la de bandera de transport. Les dues instruccions següents del codi utilitzen el mode d'adreçament immediat. Amb l'adreçament immediat, només hi ha un operand per al mnemotècnic que és un número (i ni una adreça de memòria ni de registre). Per tant, el número ha d'anar precedit de '#'. El '$' significa que el número que segueix és hexadecimal.

La segona instrucció carrega el número 3F 16 a l'acumulador. Per a la tercera instrucció, el circuit d'unitat lògica aritmètica del µP pren el transport anterior (esborrat) de 0 (forçat a 0) de la cel·la de bandera de transport, del registre d'estat i l'afegeix a 15 16 així com al valor que ja hi ha al 3F 16 acumulador i torna a posar el resultat complet a l'acumulador. En aquest cas, hi ha un transport resultant de 0. L'ALU (Unitat Lògica Aritmètica) envia (posa) 0 a la cel·la de bandera de transport del registre d'estat. El registre d'estat del processador i el registre d'estat signifiquen el mateix. Si es produeix un transport d'1, l'ALU envia 1 a la bandera de transport del registre d'estat.

Les tres línies del codi anterior han d'estar a la memòria abans de ser executades. El codi operatiu 1816 per a CLC (adreçament implícit) es troba a la ubicació de $0200 bytes. El codi operatiu A9 16 per a LDA (adreçament immediat) es troba a la ubicació de $0201 bytes. El número 3F 10 es troba a la ubicació de $0202 bytes. El codi operatiu 69 16 per a LDA (adreçament immediat) es troba a la ubicació de $0203 bytes. El número 15 10 es troba a la ubicació de $0204 bytes.

Nota: LDA és una instrucció de transferència (càrrega) i no una instrucció aritmètica (mnemotècnica).

Codi per afegir dos setze bits sense signar
Tots els registres del 6502 µP són essencialment registres de vuit bits, excepte el PC (Program Counter) que és de 16 bits. Fins i tot el registre d'estat té 8 bits d'ample, tot i que els seus vuit bits no funcionen junts. En aquesta secció, es considera l'addició de dos 16 bits sense signe, amb un transport del primer parell de vuit bits al segon parell de vuit bits. El transport d'interès aquí és el transport de la posició del vuitè bit a la posició del novè bit.

Siguin els números 0010101010111111 2 = 2ABF16 16 = 10,943 10 i 0010101010010101 2 = 2A95 16 = 10,901 10 . La suma és 0101010101010100 2 = 5554 16 = 21,844 10 .

Sumar aquests dos nombres sense signe a la base dos és el següent:

La taula següent mostra la mateixa addició amb el transport d'1 des del vuitè bit fins a la novena posició, començant per la dreta:

En codificar això, primer s'afegeixen els dos bytes inferiors. Aleshores, l'ALU (Unitat Aritmètica Lògica) envia el transport d'1 des de la vuitena posició de bit fins a la novena posició de bit, a la cel·la de bandera de transport del registre d'estat. El resultat de 0 1 0 1 0 1 0 0 sense portar va a l'acumulador. A continuació, s'afegeix el segon parell de bytes amb el transport. El mnemotècnic ADC significa afegir automàticament amb el transport anterior. En aquest cas, l'aportació anterior, que és 1, no s'ha de canviar abans de la segona addició. Per a la primera addició, com que qualsevol transport anterior no forma part d'aquesta addició completa, s'ha d'esborrar (fer 0).

Per a l'addició completa dels dos parells de bytes, la primera addició és:

A + M + 0 -> A

La segona incorporació és:

A + M + 1 -> A

Per tant, s'ha d'esborrar la bandera de transport (donat el valor 0) just abans de la primera addició. El programa següent del qual el lector ha de llegir l'explicació que segueix utilitza el mode d'adreçament absolut per a aquesta suma:

CLC
LDA $ 0213
ADC $ 0215
; no hi ha compensació perquè es necessita el valor del senyal de càrrega
STA $ 0217
LDA 0214 $
ADC $ 0216
STA $ 0218

Tingueu en compte que amb el llenguatge assemblador 6502, un punt i coma comença un comentari. Això vol dir que en l'execució del programa s'ignora el punt i coma i tot el que hi ha a la dreta. El programa que s'ha escrit prèviament està en un fitxer de text es guarda amb el nom que el programador escolli i amb l'extensió “.asm”. El programa anterior no és el programa exacte que va a la memòria per a l'execució. El programa corresponent a la memòria s'anomena programa traduït on els mnemotècnics es substitueixen amb els opcodes (bytes). Qualsevol comentari roman al fitxer de text del llenguatge assemblador i s'elimina abans que el programa traduït arribi a la memòria. De fet, hi ha dos fitxers que es guarden al disc avui: el fitxer '.asm' i el fitxer '.exe'. El fitxer “.asm” és el de la il·lustració anterior. El fitxer '.exe' és el fitxer '.asm' amb tots els comentaris eliminats i tots els mnemotècnics substituïts pels seus codis operatius. Quan s'obre en un editor de text, el fitxer '.exe' no es pot reconèixer. Llevat que s'indiqui el contrari, als efectes d'aquest capítol, el fitxer '.exe' es copia a la memòria començant des de la ubicació $0200. Aquest és l'altre significat de càrrega.

Els dos números de 16 bits que cal afegir ocupen quatre bytes a la memòria per a l'adreçament absolut: dos bytes per número (la memòria és una seqüència de bytes). Amb l'adreçament absolut, l'operand del codi operatiu es troba a la memòria. El resultat de la suma té dos bytes d'amplada i també s'ha de col·locar a la memòria. Això dóna un total de 6 10 = 6 16 bytes d'entrada i sortida. Les entrades no provenen del teclat i la sortida no és del monitor o la impressora. Les entrades es troben a la memòria (RAM) i la sortida (resultat sumant) torna a la memòria (RAM) en aquesta situació.

Abans d'executar un programa, primer ha d'estar a la memòria la versió traduïda. Mirant el codi del programa anterior, es pot veure que les instruccions sense el comentari constitueixen 19 10 = 13 16 bytes. Per tant, el programa passa des de la ubicació de $ 0200 bytes a la memòria fins a $ 0200 + $ 13 - $ 1 = $ 0212 ubicacions de bytes (a partir de $ 0200 i no $ 0201 que implica - $ 1). Afegir els 6 bytes per als números d'entrada i sortida fa que tot el programa acabi a $0212 + $6 = $0218. La durada total del programa és de 19 16 = 25 10 .

El byte inferior de l'augend hauria d'estar a l'adreça $0213, i el byte més alt del mateix augend hauria d'estar a l'adreça $0214 - little endianness. De la mateixa manera, el byte inferior de l'addend hauria d'estar a l'adreça $0215, i el byte més alt del mateix addend hauria d'estar a l'adreça $0216 - little endianness. El byte més baix del resultat (suma) hauria d'estar a l'adreça $0217, i el byte més alt del mateix resultat hauria d'estar a l'adreça $0218 - little endianness.

El codi operatiu 18 16 per a CLC (adreçament implícit) es troba a la ubicació del byte de $0200. El codi operatiu per a 'LDA $0213', és a dir, AD 16 per a LDA (adreçament absolut), es troba a la ubicació del byte de $0201. El byte inferior de l'augend que és 10111111 es troba a la ubicació del byte de memòria de $0213. Recordeu que cada codi operatiu ocupa un byte. L'adreça '$0213' de 'LDA $0213' es troba a les ubicacions dels bytes de $0202 i $0203. La instrucció 'LDA $0213' carrega el byte inferior de l'augen a l'acumulador.

El codi operatiu per a 'ADC $0215', és a dir, 6D 16 per a ADC (adreçament absolut), es troba a la ubicació del byte de $0204. El byte inferior de l'addend que és 10010101 es troba a la ubicació del byte de $0215. L'adreça '$0215' de 'ADC $0215' es troba a les ubicacions dels bytes de $0205 i $0206. La instrucció 'ADC $0215' afegeix el byte inferior de l'agregat al byte inferior de l'augend que ja es troba a l'acumulador. El resultat es torna a col·locar a l'acumulador. Qualsevol transport després del vuitè bit s'envia a la bandera de transport del registre d'estat. La cel·la del senyalador de transport no s'ha d'esborrar abans de la segona addició dels bytes més alts. Aquest transport s'afegeix automàticament a la suma dels bytes més alts. De fet, una transferència de 0 s'afegeix automàticament a la suma dels bytes inferiors al principi (equivalent a no afegir cap transport) a causa de CLC.

El comentari porta els següents 48 10 = 30 16 bytes. Tanmateix, això només es manté al fitxer de text '.asm'. No arriba a la memòria. S'elimina mitjançant la traducció que fa l'assemblador (un programa).

Per a la següent instrucció que és 'STA $0217', el codi operatiu de STA que és 8D 16 (adreça absoluta) es troba a la ubicació del byte de $0207. L'adreça '$0217' de 'STA $0217' es troba a les ubicacions de memòria de $0208 i $0209. La instrucció 'STA $0217' copia el contingut de vuit bits de l'acumulador a la ubicació de memòria de $0217.

El byte més alt de l'augend que és 00101010 es troba a la ubicació de memòria de $0214, i el byte més alt de l'agregat que és 00101010 es troba a la ubicació del byte de $02 16 . El codi operatiu per a 'LDA $0214', que és AD16 per a LDA (adreçament absolut) es troba a la ubicació del byte de $020A. L'adreça '$0214' de 'LDA $0214' es troba a les ubicacions de $020B i $020C. La instrucció 'LDA $0214' carrega el byte més alt de l'augend a l'acumulador, esborrant el que hi hagi a l'acumulador.

El codi operatiu per a 'ADC $0216', que és 6D 16 per ADC (adreçament absolut) es troba a la ubicació de bytes de $020D. L'adreça '$0216' de 'ADC 0216' es troba a les ubicacions de bytes de $020E i $020F. La instrucció 'ADC $0216' afegeix el byte més alt de l'agregat al byte més alt de l'augend que ja es troba a l'acumulador. El resultat es torna a col·locar a l'acumulador. Si hi ha un transport d'1, per a aquesta segona addició, es col·loca automàticament a la cel·la de transport del registre d'estat. Tot i que el transport més enllà del setze bit (esquerra) no és necessari per a aquest problema, és bo comprovar si s'ha produït un transport d'1 comprovant si el senyal de transport es va convertir en 1.

Per a la següent i darrera instrucció que és 'STA $0218', el codi operatiu de STA que és 8D16 (adreçament absolut) es troba a la ubicació del byte de $0210. L'adreça '$0218' de 'STA $0218' es troba a les ubicacions de memòria de $0211 i $0212. La instrucció 'STA $0218' copia el contingut de vuit bits de l'acumulador a la ubicació de memòria de $0218. El resultat de l'addició dels dos nombres de setze bits és 0101010101010100, amb el byte més baix de 01010100 a la ubicació de la memòria de $ 0217 i el byte més alt de 01010101 a la ubicació de la memòria de $ 0218 - little endianness.

Resta
Amb el 6502 µP, els nombres amb signe són números de complement a dos. El nombre de complement a dos pot ser de vuit bits, setze bits o qualsevol múltiple de vuit bits. Amb el complement de dos, el primer bit de l'esquerra és el bit del signe. Per a un nombre positiu, aquest primer bit és 0 per indicar el signe. La resta de bits formen el nombre de la manera normal. Per obtenir el complement de dos d'un nombre negatiu, inverteix tots els bits del nombre positiu corresponent i, a continuació, afegeix 1 al resultat de l'extrem dret.

Per restar un nombre positiu d'un altre nombre positiu, el resta es converteix en un nombre negatiu del complement a dos. Aleshores, el minuend i el nou nombre negatiu s'afegeixen de la manera normal. Així, la resta de vuit bits es converteix en:

On el transport s'assumeix com 1. El resultat a l'acumulador és la diferència del complement a dos. Per tant, per restar dos nombres, s'ha d'establir la bandera de transport (fer a 1).

En restar dos nombres de setze bits, la resta es fa dues vegades com si s'afegeixen dos nombres de setze bits. Com que la resta és una forma d'addició amb el 6502 µP, quan es resten dos nombres de setze bits, el senyalador de transport només s'estableix una vegada per a la primera resta. Per a la segona resta, qualsevol configuració de la bandera de transport es fa automàticament.

La programació de la resta per a nombres de vuit bits o de setze bits es fa de manera similar a la programació de la suma. Tanmateix, la bandera de transport s'ha de posar al principi. La mnemotècnica per fer-ho és:

Resta amb nombres positius de setze bits
Considereu la resta amb els nombres següents:

Aquesta resta no implica el complement de dos. Com que la resta de 6502 µP es fa en complement de dos, la resta de la base dos es fa de la següent manera:

El resultat del complement a dos és el mateix que el resultat que s'obté de la resta ordinària. Tanmateix, tingueu en compte que s'ignora l'1 que va a la dissetena posició de bit des de la dreta. El minuend i el subtrahend es divideixen en dos bits de vuit cadascun. El complement de dos de 10010110 del byte inferior del subtrahend es determina independentment del seu byte superior i de qualsevol transport. El complement de dos de 11101011 del byte superior del subtrahend es determina independentment del seu byte inferior i de qualsevol transport.

Els 16 bits del minuend ja estan en complement de dos, començant amb 0 des de l'esquerra. Per tant, no necessita cap ajust en bits. Amb el 6502 µP, el byte inferior del minuend sense cap modificació s'afegeix al byte inferior del complement de dos del subtraend. El byte inferior del minuend no es converteix en complement de dos perquè els setze bits de tot el minuend han d'estar ja en complement de dos (amb un 0 com a primer bit a l'esquerra). En aquesta primera addició, s'afegeix un transport obligatori d'1 a causa de la instrucció 1=0 SEC.

En la resta efectiva actual, hi ha un transport d'1 (de suma) del vuitè bit al novè bit (des de la dreta). Com que això és efectivament una resta, qualsevol bit que se suposa que ha d'estar a la bandera de transport al registre d'estat es complementa (inverteix). Així, el transport d'1 es converteix en 0 a la bandera C. En la segona operació, el byte més alt del minuend s'afegeix al byte de complement de dos superior del subtraend. També s'afegeix el bit de senyalització de transport complementat automàticament del registre d'estat (en aquest cas és 0) (als bytes superiors). Qualsevol 1 que va més enllà del setze bit des de la dreta s'ignora.

El següent és només codificar tot aquest esquema de la següent manera:

SEC
LDA 0213 $
SBC $ 0215
; no hi ha compensació perquè es necessita el valor del senyal de transport invertit
STA $ 0217
LDA 0214 $
SBC $ 0216
STA $ 0218

Recordeu que amb el llenguatge assemblador 6502, un punt i coma comença un comentari que no s'inclou a la versió del programa traduït a la memòria. Els dos nombres de 16 bits per a la resta ocupen quatre bytes de memòria amb adreçament absolut; dos per número (la memòria és una sèrie de bytes). Aquestes entrades no provenen del teclat. El resultat de la suma és de dos bytes i també s'ha de col·locar a la memòria en un lloc diferent. Aquesta sortida no va al monitor ni a la impressora; va a la memòria. Això dóna un total de 6 10 = 6 16 bytes per a les entrades i sortides que es col·loquen a la memòria (RAM).

Abans d'executar un programa, primer ha d'estar a la memòria. Mirant el codi del programa, es pot veure que les instruccions sense el comentari constitueixen 19 10 = 13 16 bytes. Com que tots els programes d'aquest capítol comencen des de la ubicació de memòria de $0200, el programa passa des de la ubicació de $0200 bytes a la memòria fins a la ubicació $0200 + $13 - $1 = $0212 bytes (a partir de $0200 i no $0201). Aquest interval no inclou la regió dels bytes d'entrada i sortida. Els dos números d'entrada prenen 4 bytes i el número de sortida pren 2 bytes. Afegir els 6 bytes per als números d'entrada i sortida fa que l'interval del programa acaba a $0212 + $6 = $0218. La durada total del programa és de 19 16 = 25 10 .

El byte més baix del minuend hauria d'estar a l'adreça $0213, i el byte més alt del mateix minuend hauria d'estar a l'adreça $0214 - little endianness. De la mateixa manera, el byte inferior del subtrahend hauria d'estar a l'adreça $0215, i el byte més alt del mateix subtrahend hauria d'estar a l'adreça $0216: poca endianitat. El byte més baix del resultat (diferència) hauria d'estar a l'adreça $0217, i el byte més alt del mateix resultat hauria d'estar a l'adreça $0218 - little endianness.

El codi operatiu de 38 16 per a SEC (adreçament implícit) es troba a l'adreça $0200. Se suposa que tots els programes d'aquest capítol s'inicien a la ubicació de memòria de $0200, anul·lant qualsevol programa que hi hauria estat; llevat que s'indiqui el contrari. El codi operatiu per a 'LDA $0213', és a dir, AD 16 , per a LDA (adreçament absolut) es troba a la ubicació de $0201 bytes. El byte inferior del minuend que és 10111111 es troba a la ubicació del byte de memòria de $0213. Recordeu que cada codi operatiu ocupa un byte. L'adreça '$0213' de 'LDA $0213' es troba a les ubicacions dels bytes de $0202 i $0203. La instrucció 'LDA $0213' carrega el byte inferior del minuend a l'acumulador.

El codi operatiu per a 'SBC $0215', és a dir, ED 16 , per a SBC (adreçament absolut) es troba a la ubicació de $0204 bytes. El byte inferior del subtrahend que és 01101010 es troba a la ubicació de $0215 byte. L'adreça '$0215' de 'ADC $0215' es troba a les ubicacions dels bytes de $0205 i $0206. La instrucció 'SBC $0215' resta el byte inferior del subtrahend del byte inferior del minuend que ja es troba a l'acumulador. Aquesta és la resta de complement a dos. El resultat es torna a col·locar a l'acumulador. El complement (inversió) de qualsevol transport després del vuitè bit s'envia a la bandera de transport del registre d'estat. Aquest indicador de transport no s'ha d'esborrar abans de la segona resta amb els bytes més alts. Aquest transport s'afegeix automàticament a la resta dels bytes més alts.

El comentari pren els següents 57 10 = 3916 16 bytes. Tanmateix, això només es manté al fitxer de text '.asm'. No arriba a la memòria. S'elimina mitjançant la traducció que fa l'assemblador (un programa).

Per a la següent instrucció que és 'STA $0217', el codi operatiu de STA, és a dir, 8D 16 (adreçament absolut), es troba a la ubicació de $0207 bytes. L'adreça '$0217' de 'STA $0217' es troba a les ubicacions de memòria de $0208 i $0209. La instrucció 'STA $0217' copia el contingut de vuit bits de l'acumulador a la ubicació de memòria de $0217.

El byte més alt del minuend que és 00101010 es troba a la ubicació de memòria de $0214, i el byte més alt del subtrahend que és 00010101 es troba a la ubicació del byte de $0216. El codi operatiu per a 'LDA $0214', és a dir, AD 16 per a LDA (adreçament absolut), es troba a la ubicació de $020A byte. L'adreça '$0214' de 'LDA $0214' es troba a les ubicacions de $020B i $020C. La instrucció 'LDA $0214' carrega el byte més alt del minuend a l'acumulador, esborrant el que hi hagi a l'acumulador.

El codi operatiu per a 'SBC $0216', és a dir, ED 16 per a SBC (adreçament absolut), es troba a la ubicació de $020D bytes. L'adreça '$0216' de 'SBC $0216' es troba a les ubicacions dels bytes de $020E i $020F. La instrucció 'SBC $0216' resta el byte més alt del subtrahend del byte més alt del minuend (complement de dos) que ja es troba a l'acumulador. El resultat es torna a col·locar a l'acumulador. Si hi ha un acarreament d'1 per a aquesta segona resta, el seu complement es col·loca automàticament a la cel·la de transport del registre d'estat. Tot i que el transport més enllà del setze bit (esquerra) no és necessari per a aquest problema, és bo comprovar si es produeix el transport del complement marcant la bandera de transport.

Per a la següent i darrera instrucció que és 'STA $0218', el codi operatiu de STA, és a dir, 8D 16 (adreça absoluta), es troba a la ubicació de $0210 bytes. L'adreça '$0218' de 'STA $0218' es troba a les ubicacions de memòria de $0211 i $0212. La instrucció 'STA $0218' copia el contingut de vuit bits de l'acumulador a la ubicació de memòria de $0218. El resultat de la resta amb els dos nombres de setze bits és 0001010101010101 amb el byte més baix de 01010101 a la ubicació de la memòria de $ 0217 i el byte més alt de 00010101 a la ubicació de la memòria de $ 0218 - little endianness.

El 6502 µP només té circuits per a la suma, i indirectament per a la resta del complement de dos. No té circuits per a la multiplicació i la divisió. Per fer la multiplicació i la divisió, s'ha d'escriure un programa de llenguatge ensamblador amb detalls, inclòs el desplaçament de productes parcials i dividends parcials.

4.4 Operacions lògiques

En el 6502 µP, el mnemotècnic per a OR és ORA i el mnemotècnic per a OR exclusiu és EOR. Observeu que les operacions lògiques no tenen l'adreçament implícit. L'adreçament implícit no pren cap operand. Cadascun dels operadors lògics ha de prendre dos operands. El primer es troba a l'acumulador i el segon a la memòria o a la instrucció. El resultat (8 bits) torna a l'acumulador. El primer de l'acumulador es posa allà mitjançant una instrucció immediata o es copia de la memòria amb adreçament absolut. En aquesta secció, només s'utilitza l'adreçament de pàgina zero per il·lustrar. Aquests operadors lògics són tots operadors bit a bit.

I
La taula següent il·lustra el AND bit a bit en binari, hexadecimal i decimal:

Tots els programes d'aquest capítol haurien de començar a la ubicació de bytes de memòria de $0200. Tanmateix, els programes d'aquesta secció es troben a la pàgina zero, amb l'objectiu d'il·lustrar l'ús de la pàgina zero sense el byte superior de 00000000 2 . L'ANDing anterior es pot codificar de la següent manera:

LDA #$9A ; no de memòria - adreçament immediat
I #$CD ; no de memòria - adreçament immediat
STA $ 30; emmagatzema 88 $ a 0030 $ en base zero

O
La taula següent il·lustra l'OR bit a bit en binari, hexadecimal i decimal:

LDA #$9A ; no de memòria - adreçament immediat
ORA #$CD ; no de memòria - adreçament immediat
STA $ 30; emmagatzema $ CF a 0030 $ en base zero

GRATIS
La taula següent il·lustra la XOR per bits en binari, hexadecimal i decimal:

LDA #$9A ; no de memòria - adreçament immediat
EOR #$CD ; no de memòria - adreçament immediat
STA $ 30; emmagatzema 57 $ a 0030 $ en base zero

4.5 Operacions de canvi i rotació

Els mnemotècnics i els codis operatius per als operadors de canvi i rotació són:

ASL: desplaça un bit cap a l'esquerra de l'acumulador o la ubicació de memòria, inserint 0 a la cel·la de l'extrem dret desocupada.

LSR: Desplaceu cap a la dreta un bit de l'acumulador o la ubicació de memòria, inserint 0 a la cel·la de l'esquerra.
ROL: Gireu un bit a l'esquerra de la ubicació de l'acumulador o de la memòria, inserint el bit que es deixa anar a l'esquerra a la cel·la de l'extrem dret.
ROR: Gireu un bit a la dreta de l'acumulador o la ubicació de memòria, inserint el bit que s'ha deixat a la dreta a la cel·la de l'esquerra.

Per fer un canvi o rotació amb l'acumulador, la instrucció és una cosa així:

LSR A

Això utilitza un altre mode d'adreçament anomenat mode d'adreçament acumulador.

Per fer un canvi o rotació amb una ubicació de memòria de bytes, la instrucció és una cosa així:

ROR $ 2BCD

On 2BCD és la ubicació de la memòria.

Tingueu en compte que no hi ha cap mode d'adreçament immediat o implícit per canviar o girar. No hi ha un mode d'adreçament immediat perquè no té sentit canviar o girar un número que només queda a la instrucció. No hi ha un mode d'adreçament implícit perquè els dissenyadors del 6502 µP volen que només el contingut de l'acumulador (registre A) o la ubicació d'un byte de memòria es desplaci o giri.

4.6 Mode d'adreçament relatiu

El microprocessador sempre augmenta (en 1, 2 o 3 unitats) el comptador de programes (PC) per apuntar a la següent instrucció que s'ha d'executar. El 6502 µP té una instrucció la mnemotècnica de la qual és BVS, que significa Branch on Overflow Set. El PC consta de dos bytes. Aquesta instrucció fa que l'ordinador tingui una adreça de memòria diferent per a la següent instrucció que s'executa no com a resultat d'un increment normal. Ho fa afegint o restant un valor, anomenat desplaçament, al contingut de l'ordinador. Així, l'ordinador apunta a una ubicació de memòria diferent (ramificada) perquè l'ordinador continuï executant-se des d'allà. El desplaçament és un nombre enter de -128 10 a +127 10 (complement de dos). Per tant, el desplaçament pot fer que el salt continuï endavant a la memòria. Si és positiu o endarrerit en la memòria, o si és negatiu.

La instrucció BVS només pren un operand que és el desplaçament. BVS utilitza l'adreçament relatiu. Tingueu en compte la següent instrucció:

BVS $ 7F

A la base dos, 7F H és 01111111 2 = 127 10 . Suposem que el contingut de l'ordinador per a la següent instrucció és de $0300. La instrucció BVS fa que s'afegeixin $ 7F (un nombre positiu que ja està en el complement de dos) a $ 0300 per donar $ 037F. Per tant, en lloc de la següent instrucció que s'executarà a la ubicació de memòria de $0300, és a la ubicació de memòria de $037F (aproximadament mitja pàgina de diferència).

Hi ha altres instruccions de branca, però BVS és molt bona per il·lustrar l'adreçament relatiu. L'adreçament relatiu tracta les instruccions de la sucursal.

4.7 Adreçament indexat i adreçament indirecte per separat

Aquests modes d'adreçament permeten al 6502 µP gestionar les enormes quantitats de dades en períodes curts de temps amb un nombre reduït d'instruccions. Hi ha ubicacions de 64 KB per a tota la memòria Comodore-64. Per tant, per accedir a qualsevol ubicació de bytes, de 16 bits, cal fer dos bytes. L'única excepció a la necessitat de dos bytes és per a la pàgina zero on s'omet el byte més alt de $00 per estalviar l'espai que ocupa la instrucció a la memòria. Amb un mode d'adreçament diferent a la pàgina zero, tant els bytes superiors com els inferiors de l'adreça de memòria de 16 bits s'indiquen principalment d'alguna manera.

Adreçament indexat bàsic

Adreçament d'índex absolut
Recordeu que el registre X o Y s'anomena registre d'índex. Tingueu en compte la següent instrucció:

LDA $ C453,X

Suposem que el valor de 6 H està al registre X. Tingueu en compte que 6 no s'escriu en cap lloc de la instrucció. Aquesta instrucció afegeix el valor de 6H a C453 H que forma part de la instrucció mecanografiada al fitxer de text que encara s'ha de muntar – C453 H + 6 H = C459 H . LDA significa carregar un byte a l'acumulador. El byte que s'ha de carregar a l'acumulador prové de l'adreça $C459. El $C459, que és la suma de $C453 que s'escriu amb la instrucció i 6 H que es troba al registre X es converteix en l'adreça efectiva de la qual prové el byte que s'ha de carregar a l'acumulador. Si 6 H estava al registre Y, Y s'escriu en lloc de X a la instrucció.

A la instrucció d'instrucció escrita, $C453 es coneix com l'adreça base i la 6 H al registre X o Y es coneix com la part de recompte o índex de l'adreça efectiva. L'adreça base pot referir-se a qualsevol adreça de bytes de la memòria i als 256 següents 10 es pot accedir a les adreces, suposant que l'índex (o recompte) iniciat al registre X o Y és 0. Recordeu que un byte pot donar un rang continu de fins a 256 10 números (és a dir, 00000000 2 al 11111111 2 ).

Així, l'adreçament absolut afegeix allò que ja s'ha posat (ha estat posat per una altra instrucció) al registre X o Y a les 16 adreces que s'escriuen amb la instrucció per obtenir l'adreça efectiva. A la instrucció mecanografiada, els dos registres d'índex es distingeixen per X o Y que s'escriuen després d'una coma. S'escriu X o Y; no tots dos.

Després d'escriure tot el programa en un editor de text i desar amb el nom de fitxer d'extensió '.asm', l'assemblador, que és un altre programa, ha de traduir el programa escrit al que està (carregat) a la memòria. La instrucció anterior, que és 'LDA $C453,X', ocupa tres ubicacions de bytes a la memòria, i no cinc.

Recordeu que un mnemotècnic com LDA pot tenir més d'un codi operatiu (bytes diferents). El codi operatiu de la instrucció que utilitza el registre X és diferent del codi operatiu que utilitza el registre Y. L'assemblador sap quin codi operatiu utilitzar en funció de la instrucció teclejada. El codi operatiu d'un byte per a 'LDA $C453,X' és diferent del codi operatiu d'un byte per a 'LDA $C453,Y'. De fet, el codi operatiu per a LDA a 'LDA $C453,X' és BD i el codi operatiu per a LDA a 'LDA $C453,9' és BD.

Si el codi operatiu per a LDA es troba a la ubicació de $0200 bytes. Aleshores, l'adreça de 16 bits de $C453 ocupa les ubicacions de bytes de la memòria que són $0201 i $0202. El byte del codi operatiu en particular indica si el que està implicat és el registre X o el registre Y. Per tant, la instrucció de llenguatge muntat que és 'LDA $C453,X' o 'LDA $C453,Y' ocupa tres bytes consecutius a la memòria, i no quatre o cinc.

Adreçament indexat de pàgines zero
L'adreçament d'índex de pàgina zero és com l'adreçament d'índex absolut que es descriu anteriorment, però el byte objectiu només ha d'estar a la pàgina zero (de $0000 a $00FF). Ara, quan es tracta de la pàgina zero, el byte més alt que sempre és 00 H per a les ubicacions de memòria normalment s'evita. Per tant, normalment s'esmenta que la pàgina zero comença des de $ 00 fins a FF. Per tant, la instrucció anterior de 'LDA $C453,X' és:

LDA 53,X $

El $C4, un byte superior que fa referència a una pàgina per sobre de la pàgina zero, no es pot utilitzar en aquesta instrucció, ja que posa el byte de destinació esperat que es carregui al byte acumulat fora i per sobre de la pàgina zero.

Quan el valor que s'escriu a la instrucció s'afegeix al valor del registre d'índex, la suma no hauria de donar un resultat per sobre de la pàgina zero (FF H ). Per tant, està fora de dubte tenir una instrucció com 'LDA $FF, X' i un valor com FF H al registre d'índex perquè FF H + FF H = 200 H que és la ubicació del primer byte (0200 $) de la pàgina 2 (tercera pàgina) a la memòria, està a una gran distància de la pàgina 0. Per tant, amb l'adreçament indexat de pàgina zero, l'adreça efectiva ha d'estar a la pàgina zero.

Adreçament indirecte

Jump Adreçament absolut
Abans de parlar de l'adreçament indirecte absolut, és bo mirar primer l'adreçament absolut de JMP. Suposem que l'adreça que té el valor d'interès (byte objectiu) és 8765 $. Es tracta de 16 bits formats per dos bytes: el byte superior, que és 87 H i el byte inferior que és 65 H . Per tant, els dos bytes per $ 8765 es posen a l'ordinador (comptador de programes) per a la següent instrucció. El que s'escriu al programa de llenguatge ensamblador (fitxer) és:

JMP $ 8765

El programa en execució a la memòria salta des de qualsevol adreça a la qual va accedir a 8765 $. El mnemotècnic JMP té tres codis operatius que són 4C, 6C i 7C. El codi operatiu per a aquest adreçament absolut és 4C. El codi operatiu per a l'adreçament indirecte absolut JMP és 6C (consulteu les il·lustracions següents).

Adreçament indirecte absolut
Això només s'utilitza amb la instrucció jump (JMP). Suposem que l'adreça que té el byte d'interès (byte objectiu) és 8765 $. Es tracta de 16 bits formats per dos bytes: el byte superior, que és 87 H i el byte inferior que és 65 H . Amb l'adreçament indirecte absolut, aquests dos bytes es troben en realitat en dues ubicacions de bytes consecutives en altres llocs de la memòria.

Suposem que es troben a les ubicacions de memòria de $0210 i $0211. A continuació, el byte inferior de l'adreça d'interès que és 65 H es troba a l'adreça $0210 i el byte més alt que és 87 H es troba a l'adreça $0211. Això vol dir que el byte d'interès de memòria més baix va a l'adreça consecutiva més baixa, i el byte d'interès de memòria més alt va a l'adreça consecutiva més alta: poca endianitat.

L'adreça de 16 bits pot fer referència a dues adreces consecutives a la memòria. En aquest sentit, l'adreça $0210 fa referència a les adreces de $0210 i $0211. El parell d'adreces de $0210 i $0211 conté l'adreça final (16 bits de dos bytes) del byte objectiu, amb el byte inferior de 65 H en $ 0210 i el byte superior de 87 H en 0211 $. Per tant, la instrucció de salt que s'escriu és:

JMP (0210 $)

El mnemotècnic JMP té tres codis operatius que són 4C, 6C i 7C. El codi operatiu per a l'adreçament indirecte absolut és 6C. El que s'escriu al fitxer de text és 'JMP ($0210)'. A causa dels parèntesis, l'assemblador (traductor) utilitza el codi operatiu 6C per a JMP, i no 4C o 7C.

Amb l'adreçament indirecte absolut, en realitat hi ha tres regions de memòria. La primera regió pot consistir en les ubicacions de bytes de $0200, $0201 i $0202. Això té els tres bytes per a la instrucció 'JMP ($0210)'. La segona regió, que no és necessàriament al costat de la primera, consta de les dues ubicacions de bytes consecutives de $0210 i $0211. És el byte inferior aquí ($0210) que s'escriu a la instrucció del programa en llenguatge ensamblador. Si l'adreça d'interès és de 8765 $, el byte inferior és 65 H es troba a la ubicació de $0210 bytes i el byte superior de 87 H es troba a la ubicació de $0211 bytes. La tercera regió consta de només una ubicació d'un byte. És de l'adreça de $ 8765 per al byte de destinació (byte d'interès final). El parell d'adreces consecutives, $0210 i $0211, conté el punter de $8765 que és l'adreça d'interès. Després de la interpretació informàtica, són 8765 $ els que s'introdueixen al PC (Comptador de programes) per accedir al byte de destinació.

Adreçament indirecte de pàgina zero
Aquest adreçament és el mateix que l'adreçament indirecte absolut, però el punter ha d'estar a la pàgina zero. L'adreça de byte inferior de la regió del punter és la que hi ha a la instrucció escrita de la següent manera:

JMP (50 $)

El byte més alt del punter es troba a la ubicació de $51 bytes. L'adreça efectiva (apuntat) no ha d'estar a la pàgina zero.

Així, amb l'adreçament d'índex, el valor d'un registre d'índex s'afegeix a l'adreça base que es dóna a la instrucció per tenir l'adreça efectiva. L'adreçament indirecte utilitza un punter.

4.8 Adreçament indirecte indexat

Adreçament indirecte indexat absolut
Aquest mode d'adreçament només s'utilitza amb la instrucció JMP.
Amb l'adreçament indirecte absolut, hi ha el valor apuntat (byte) amb les seves pròpies dues adreces de bytes consecutives. Aquestes dues adreces consecutives formen el punter per estar a la regió del punter de dos bytes consecutius a la memòria. El byte inferior de la regió del punter és el que s'escriu a la instrucció entre parèntesis. El punter és l'adreça del valor apuntat. En la situació anterior, 8765 $ és l'adreça del valor apuntat. El $0210 (seguit de $0211) és l'adreça el contingut de la qual és $8765 que és el punter. Amb el mode d'adreçament indirecte absolut, és ($0210) el que s'escriu al programa (fitxer de text), inclosos els parèntesis.

D'altra banda, amb el mode d'adreçament indirecte indexat absolut, el byte d'adreça inferior per a la regió del punter es forma afegint el valor del registre X a l'adreça escrita. Per exemple, si el punter es troba a la ubicació de l'adreça de $0210, la instrucció escrita pot ser una cosa com aquesta:

JMP ($020A,X)

On el registre X té el valor de 6 H . 020A H + 6 H = 0210 H . El registre Y no s'utilitza amb aquest mode d'adreçament.

Adreçament indirecte sense pàgina indexada
Aquest mode d'adreçament utilitza el registre X i no el registre Y. Amb aquest mode d'adreçament, encara hi ha el valor apuntat i el punter a la seva regió de punter d'adreça de dos bytes. Hi ha d'haver dos bytes consecutius a la pàgina zero per al punter. L'adreça que s'escriu a la instrucció és una adreça d'un byte. Aquest valor s'afegeix al valor del registre X i es descarta qualsevol transport. El resultat apunta a la regió del punter de la pàgina 0. Per exemple, si l'adreça d'interès (apuntada) és $8765 i es troba a les ubicacions dels bytes de $50 i $51 de la pàgina 0, i el valor al registre X és $30, el la instrucció mecanografiada és una cosa així:

LDA (20 $)

Perquè 20 $ + 30 $ = 50 $.

Adreçament indexat indirecte
Aquest mode d'adreçament utilitza el registre Y i no el registre X. Amb aquest mode d'adreçament, encara hi ha el valor apuntat i la regió del punter, però el contingut de la regió del punter funciona de manera diferent. Hi ha d'haver dos bytes consecutius a la pàgina zero per a la regió del punter. L'adreça inferior de la regió del punter s'escriu a la instrucció. Aquest nombre (parell de bytes) que està contingut a la regió del punter s'afegeix al valor del registre Y per tenir el punter real. Per exemple, deixeu que l'adreça d'interès (apuntada) sigui $ 8765, el valor de 6H estigui al registre Y i el número (dos bytes) sigui a l'adreça de 50 H i 51 H . Els dos bytes junts són $ 875F ja que $ 875F + $ 6 = $ 8765. La instrucció escrita és una cosa així:

LDA ($50),I

4.9 Instruccions d'increment, decrement i BIT de prova

La taula següent mostra les operacions de les instruccions d'increment i decrement:

L'INA i el DEA augmenten i decreixen l'acumulador, respectivament. Això s'anomena adreçament acumulador. INX, DEX, INY i DEY són per als registres X i Y, respectivament. No prenen cap operand. Per tant, utilitzen el mode d'adreçament implícit. Increment significa afegir 1 al byte de registre o de memòria. Decrement significa restar 1 del byte de registre o memòria.

INC i DEC incrementen i disminueixen un byte de memòria, respectivament (i no un registre). L'ús de l'adreçament de pàgina zero en lloc de l'adreçament absolut és estalviar la memòria per a la instrucció. L'adreçament de pàgina zero és un byte menys que l'adreçament absolut de la instrucció a la memòria. Tanmateix, el mode d'adreçament de la pàgina zero afecta només la pàgina zero.

La instrucció BIT prova els bits d'un byte a la memòria amb els 8 bits de l'acumulador, però no canvia cap dels dos. Només s'estableixen alguns indicadors del registre d'estat del processador 'P'. Els bits de la ubicació de memòria especificada s'agrupen lògicament amb els de l'acumulador. A continuació, s'estableixen els següents bits d'estat:

  • N que és el bit 7 i l'últim bit (esquerra) del registre d'estat, rep el bit 7 de la ubicació de memòria abans de l'ANDing.
  • V que és el bit 6 del registre d'estat rep el bit 6 de la ubicació de memòria abans de l'ANDing.
  • La bandera Z del registre d'estat s'estableix (fa 1) si el resultat de l'AND és zero (00000000 2 ). En cas contrari, s'esborra (es fa 0).

4.10 Comparar instruccions

Els mnemotècnics de les instruccions de comparació per al 6502 µP són CMP, CPX i CPY. Després de cada comparació, els senyals N, Z i C del registre d'estat del processador 'P' es veuen afectats. La bandera N s'estableix (fa 1) quan el resultat és un nombre negatiu. La bandera Z s'estableix (fa 1) quan el resultat és un zero (000000002). La bandera C s'estableix (fa 1) quan hi ha un transport del vuit al novè bit. La taula següent ofereix una il·lustració detallada

Significa 'més gran que'. Amb això, la taula de comparació hauria de ser autoexplicativa.

4.11 Instruccions de salt i ramificació

La taula següent resumeix les instruccions de salt i ramificació:

La instrucció JMP utilitza l'adreçament absolut i indirecte. La resta d'instruccions de la taula són instruccions de branca. Utilitzen només l'adreçament relatiu amb el 6502 µP. Amb això, la taula s'explica per si mateixa si es llegeix d'esquerra a dreta i de dalt a baix.

Tingueu en compte que les branques només es poden aplicar a adreces dins de -128 a +127 bytes des de l'adreça indicada. Això és un adreçament relatiu. Tant per a les instruccions JMP com per a les branques, el comptador de programes (PC) es veu directament afectat. El 6502 µP no permet que les branques arribin a una adreça absoluta, tot i que el salt pot fer l'adreçament absolut. La instrucció JMP no és una instrucció de branca.

Nota: L'adreçament relatiu només s'utilitza amb instruccions de branca.

4.12 L'àrea de la pila

Una subrutina és com un dels programes curts anteriors per sumar dos nombres o restar dos nombres. L'àrea de pila de la memòria comença des de $ 0100 fins a $ 01FF ambdós inclosos. Aquesta àrea s'anomena simplement pila. Quan el microprocessador executa un salt a la instrucció de subrutina (JSR - consulteu la discussió següent), necessita saber on tornar quan hagi acabat. El 6502 µP manté aquesta informació (adreça de retorn) a la memòria baixa de $0100 a $01FF (l'àrea de la pila) i utilitza el contingut del registre del punter de pila que és 'S' al microprocessador com a punter (9 bits) a l'última adreça retornada. que s'emmagatzema a la pàgina 1 ($0100 a $01FF) de la memòria. La pila creix des de $ 01FF i fa possible niar les subrutines fins a 128 nivells de profunditat.

Un altre ús del punter de pila és gestionar les interrupcions. El 6502 µP té els pins etiquetats com IRQ i NMI. És possible que alguns petits senyals elèctrics s'apliquin a aquests pins i facin que el 6502 µP deixi d'executar un programa i que comenci a executar-ne un altre. En aquest cas, el primer programa s'interromp. Igual que les subrutines, els segments de codi d'interrupció es poden anidar. El processament d'interrupcions es tracta al capítol següent.

Nota : el punter de pila té 8 bits per a l'adreça de byte inferior per adreçar les ubicacions de $0100 a $01FF. El byte més alt és 00000001 2 s'assumeix.

La taula següent ofereix les instruccions que relacionen el punter de pila 'S' amb els registres A, X, Y i P amb l'àrea de pila de la memòria:

4.13 Trucada i retorn de subrutina

Una subrutina és un conjunt d'instruccions que aconsegueixen un objectiu determinat. El programa anterior de sumes o restes és una subrutina molt curta. De vegades, les subrutines només s'anomenen rutines. La instrucció per cridar una subrutina és:

JSR: Anar a la subrutina

La instrucció per tornar d'una subrutina és:

RTS: Tornar de la subrutina

El microprocessador té la tendència a executar contínuament les instruccions a la memòria, una rere l'altra. Suposem que el microprocessador està executant un segment de codi i troba una instrucció de salt (JMP) per anar a executar un segment de codi que està codificat darrere del qual ja s'ha executat. Executa aquest segment de codi darrere i continua executant tots els segments de codi (instruccions) seguint el segment de codi darrere, fins que torna a executar el segment de codi actual i continua a continuació. JMP no envia la següent instrucció a la pila.

A diferència de JMP, JSR envia l'adreça de la següent instrucció després d'ella des del PC (comptador de programes) a la pila. La posició de la pila d'aquesta adreça es col·loca al punter de pila 'S'. Quan es troba (executa) una instrucció RTS a la subrutina, l'adreça que s'empeny a la pila s'escapa de la pila i el programa es reprèn a aquesta adreça extreta que és la següent adreça d'instrucció just abans de la trucada de la subrutina. L'última adreça que s'elimina de la pila s'envia al comptador del programa. La taula següent ofereix els detalls tècnics de les instruccions JSR i RTS:

Vegeu la il·lustració següent per als usos de JSR i RTS:

4.14 Un exemple de bucle de compte enrere

La subrutina següent compta enrere des de $FF fins a $00 (un total de 256 10 compta):

iniciar LDX #$FF ; carrega X amb $FF = 255
bucle DEX; X = X – 1
bucle BNE; si X no és zero, aneu al bucle
RTS ; tornar

Cada línia té un comentari. Els comentaris mai entren a la memòria per a l'execució. L'assemblador (traductor) que converteix un programa al que està a la memòria per a l'execució (execució) sempre elimina els comentaris. Un comentari comença amb ';' . El 'inici' i el 'bucle' d'aquest programa s'anomenen etiquetes. Una etiqueta identifica (el nom) per a l'adreça de la instrucció. Si la instrucció és una instrucció d'un sol byte (adreçament implícit), l'etiqueta és l'adreça d'aquesta instrucció. Si la instrucció és una instrucció multibyte, l'etiqueta identifica el primer byte per a la instrucció multibyte. La primera instrucció d'aquest programa consta de dos bytes. Suposant que comença a l'adreça $ 0300, l'adreça $ 0300 es pot substituir per 'inici' al programa. La segona instrucció (DEX) és una instrucció d'un sol byte i hauria d'estar a l'adreça $0302. Això vol dir que l'adreça $0302 es pot substituir per 'bucle', cap avall al programa, que en realitat és així a 'bucle BNE'.

'Bucle BNE' significa la branca a l'adreça donada quan la bandera Z del registre d'estat és 0. Quan el valor del registre A o X o Y és 00000000 2 , a causa de l'última operació, la bandera Z és 1 (establert). Així, mentre que és 0 (no 1), la segona i la tercera instruccions del programa es repeteixen en aquest ordre. En cada seqüència repetida, el valor (número sencer) del registre X es redueix en 1. DEX significa X = X – 1. Quan el valor del registre X és $00 = 00000000 2 , Z es converteix en 1. En aquest punt, no hi ha més repetició de les dues instruccions. La darrera instrucció RTS del programa, que és una instrucció d'un sol byte (adreçament implícit), torna de la subrutina. L'efecte d'aquesta instrucció és fer que l'adreça del comptador del programa sigui a la pila per al codi que s'ha d'executar abans de la trucada de subrutina i tornar al comptador del programa (PC). Aquesta adreça és l'adreça de la instrucció que s'ha d'executar abans de cridar la subrutina.

Nota: Quan s'escriu un programa de llenguatge assemblador per al 6502 µP, només ha de començar una etiqueta al començament d'una línia; qualsevol altre codi de línia s'ha de desplaçar almenys un espai cap a la dreta.

Crida a una subrutina
Ignorant l'espai de memòria que ocupen les etiquetes anteriors, el programa pren 6 bytes d'ubicacions consecutives a la memòria (RAM) de $ 0300 a $ 0305. En aquest cas, el programa és:

LDX #$FF ; carrega X amb $FF = 255
DEX ; X = X – 1
BNE $ 0302 ; si X no és zero, aneu al bucle
RTS ; tornar

A partir de l'adreça $0200 a la memòria pot ser la trucada per a la subrutina. La instrucció de trucada és:

Inici JSR; L'inici és l'adreça $0300, és a dir, JSR $0300

La subrutina i la seva crida que estan correctament escrites al fitxer de l'editor de text és:

iniciar LDX #$FF; carrega X amb $FF = 255
bucle DEX; X = X – 1

bucle BNE; si X no és zero, aneu al bucle
RTS ; tornar

Inici JSR: saltar a la rutina a partir de 0300 $

Ara, hi pot haver moltes subrutines en un programa llarg. Tots ells no poden tenir el nom 'inici'. Haurien de tenir noms diferents. De fet, cap d'ells podria tenir el nom 'inici'. 'Inici' s'utilitza aquí per motius docents.

4.15 Traducció d'un programa

Traduir un programa o muntar-lo significa el mateix. Considereu el programa següent:

iniciar LDX #$FF: carregar X amb $FF = 255
bucle DEX : X = X – 1
Bucle BNE: si X no és zero, aneu al bucle
RTS: tornar
Inici JSR: saltar a la rutina a partir de 0300 $

Aquest és el programa que s'ha escrit prèviament. Consisteix en la subrutina, l'inici i la trucada a la subrutina. El programa compta enrere des de 255 10 a 0 10 . El programa comença a l'adreça inicial de l'usuari de $0200 (RAM). El programa s'escriu en un editor de text i es desa al disc. Té un nom com 'sample.asm' on 'sample' és el nom de l'elecció del programador, però l'extensió '.asm' per al llenguatge ensamblador ha d'estar associada amb el nom del fitxer.

El programa ensamblat és produït per un altre programa que s'anomena assemblador. L'assemblador és subministrat pel fabricant del 6502 µP o per un tercer. L'assemblador reprodueix el programa de tal manera que estigui a la memòria (RAM) mentre s'executa (executa).

Suposem que la instrucció JSR comença a l'adreça $0200 i la subrutina comença a l'adreça $0300. El muntador elimina tots els comentaris i espais en blanc. Els comentaris i els espais en blanc malgasten la memòria que sempre és escassa. Una possible línia en blanc entre el segment de codi de subrutina anterior i la trucada de subrutina és un exemple d'espai en blanc. El fitxer muntat encara es desa al disc i s'anomena com a 'sample.exe'. La 'mostra' és el nom de l'elecció del programador, però l'extensió '.exe' hauria d'estar allà per indicar que és un fitxer executable.

El programa muntat es pot documentar de la següent manera:

Es diu que produir un document com aquest és un muntatge a mà. Tingueu en compte que els comentaris d'aquest document no apareixen a la memòria (per a l'execució). La columna d'adreces de la taula indica les adreces inicials de les instruccions a la memòria. Tingueu en compte que 'JSR start', que és 'JSR $0300', que s'espera que estigui codificat com '20 03 00', en realitat està codificat com '20 00 03' amb l'adreça de byte de memòria inferior prenent el byte inferior a la memòria i el una adreça de bytes de memòria més alta que pren el byte més gran de la memòria: poca endianitat. El codi operatiu per a JSR és 20 16 .

Tingueu en compte que el desplaçament d'una instrucció de branca com ara BNE és un nombre de complement a dos en el rang de 128 10 fins a +127 10 . Per tant, 'bucle BNE' significa 'BNE -1 10 ” que en realitat és “D0 FF” en la forma de codi de FF 16 és -1 en el complement a dos que s'escriu com a = 11111111 en la base dos. El programa assemblador substitueix les etiquetes i els camps per nombres hexadecimals reals (els números hexadecimals són números binaris que s'agrupen en quatre bits). Les adreces reals on comença cada instrucció s'inclouen realment.

Nota: La instrucció 'JSR start' es substitueix per instruccions més curtes que envien el contingut actual (bytes alts i baixos) del comptador del programa a la pila amb el punter de pila que es decrementa dues vegades (una vegada per a byte alt i una altra per a byte baix) i després torna a carregar l'ordinador amb l'adreça $0300. El punter de pila ara apunta a $00FD, suposant que s'ha inicialitzat a $01FF.

A més, la instrucció RTS es substitueix per una sèrie d'instruccions més curtes que incrementen el punter de pila 'S' dues vegades (una vegada per a byte baix i una altra per a byte alt) i treu els dos bytes d'adreça corresponents des del punter de pila a l'ordinador per a la següent instrucció.

Nota: El text d'una etiqueta no ha de tenir més de 8 caràcters.

El 'bucle BNE' utilitza l'adreçament relatiu. Significa afegir -3 10 al següent contingut del comptador del programa de 0305 $. Els bytes per al 'bucle BNE' són 'D0 FD' on FD és el complement de dos de -3 10 .

Nota: aquest capítol no presenta totes les instruccions per al 6502 µP. Totes les instruccions i els seus detalls es poden trobar al document titulat 'Família de microprocessadors SY6500 de 8 bits'. Hi ha un fitxer PDF amb el nom “6502.pdf” per a aquest document que està disponible gratuïtament a Internet. El 6502 µP que es descriu en aquest document és 65C02.

4.16 Interrupcions

Els senyals de qualsevol dispositiu que estigui connectat als ports externs (superfície vertical) del Commodore 64 han de passar pels circuits (IC) CIA 1 o CIA 2 abans d'arribar al microprocessador 6502. Els senyals del bus de dades del 6502 µP han de passar pel xip CIA 1 o CIA 2 abans d'arribar a qualsevol dispositiu extern. CIA són les sigles de Complex Interface Adapter. A la figura 4.1 'Diagrama de blocs de la placa base Commodore_64', els dispositius d'entrada/sortida de bloc representen el CIA 1 i el CIA 2. Quan un programa s'està executant, es pot interrompre per executar algun altre fragment de codi abans de continuar. Hi ha interrupció de maquinari i interrupció de programari. Per a la interrupció del maquinari, hi ha dos pins de senyal d'entrada al 6502 µP. Els noms d'aquests pins són IRQ i NMI . Aquestes no són línies de dades µP. Les línies de dades per al µP són D7, D6, D5, D4, D3, D2, D1 i D0; amb D0 per al bit menys significatiu i D7 per al bit més significatiu.

IRQ significa Interrupt ReQuest 'active' low. Aquesta línia d'entrada al µP és normalment alta, a aproximadament 5 volts. Quan baixa a aproximadament 0 volts, és una sol·licitud d'interrupció que indica el µP. Tan bon punt s'accepta la sol·licitud, la línia torna alta. Atorgar la sol·licitud d'interrupció significa que el µP es ramifica al codi (subrutina) que gestiona la interrupció.

NMI significa interrupció no emmascarable 'activa' baixa. Mentre que el codi per IRQ s'està executant NMI pot baixar. En aquest cas, NMI es gestiona (s'executa el seu propi codi). Després d'això, el codi per IRQ continua. Després del codi per IRQ finalitza, el codi del programa principal continua. Això és, NMI interromp el IRQ manipulador. El senyal per NMI encara es pot donar al µP fins i tot quan el µP està inactiu i no gestiona res o no executa un programa principal.

Nota: En realitat és la transició d'alt a baix, de NMI , això és el NMI senyal, més sobre això més endavant. IRQ normalment prové de la CIA 1 i NMI normalment prové de la CIA 2. NMI , que significa interrupció no emmascarable, es pot considerar com una interrupció no aturable.

Tractament d'interrupcions
Si la petició és de IRQ o NMI , la instrucció actual s'ha de completar. El 6502 només té els registres A, X i Y. Mentre una subrutina està funcionant, pot estar utilitzant aquests tres registres junts. Un gestor d'interrupcions segueix sent una subrutina, encara que no es veu com a tal. Un cop completada la instrucció actual, el contingut dels registres A, X i Y del 65C02 µP es desa a la pila. L'adreça de la següent instrucció del comptador de programes també s'envia a la pila. Aleshores, el µP es ramifica al codi de la interrupció. Després d'això, el contingut dels registres A, X i Y es restaura des de la pila en l'ordre invers al qual s'envien.

Exemple de codificació d'una interrupció
Per simplificar, suposa que la rutina per a µP IRQ interrupció és només afegir els números $01 i $02 i desar el resultat de $03 a l'adreça de memòria de $0400. El codi és:

ISR PHA
PHX
PHY
;
LDA #$01
ADC #$02
COSTEEN 0400 $
;
PLY
PLX
PLA
RTI

ISR és una etiqueta i identifica l'adreça de memòria on es troba la instrucció PHA. ISR significa Rutina de servei d'interrupció. PHA, PHX i PHY envien el contingut dels registres A, X i Y a la pila amb l'esperança que sigui necessari per qualsevol codi (programa) que s'està executant just abans de la interrupció. Les tres instruccions següents formen el nucli del controlador d'interrupcions. Les instruccions PLY, PLX i PLA han d'estar en aquest ordre i retornen el contingut dels registres Y, X i A. L'última instrucció, que és RTI, (sense operand) retorna la continuació de l'execució a qualsevol codi (programa) que s'està executant abans de la interrupció. RTI recupera l'adreça de la següent instrucció del codi que s'està executant de la pila al comptador del programa. RTI significa Retorn de la interrupció. Amb això, el maneig d'interrupcions (subrutina) s'ha acabat.

Interrupció de programari
La forma principal d'haver una interrupció de programari per al 6502 µP és amb l'ús de la instrucció d'adreça implícita BRK. Suposem que el programa principal s'està executant i troba la instrucció BRK. A partir d'aquest moment, l'adreça de la següent instrucció a l'ordinador s'ha d'enviar a la pila a mesura que es completa la instrucció actual. Una subrutina per gestionar les instruccions del programari s'hauria d'anomenar 'següent'. Aquesta subrutina d'interrupció hauria d'empènyer el contingut del registre A, X i Y a la pila. Després d'executar el nucli de la subrutina, el contingut dels registres A, X i Y s'hauria de treure de la pila als seus registres mitjançant la subrutina completa. L'última declaració de la rutina és RTI. El contingut de l'ordinador també es retira automàticament de la pila a l'ordinador a causa de RTI.

Comparació i contrast de subrutina i rutina de servei d'interrupció
La taula següent compara i contrasta la subrutina i la rutina del servei d'interrupció:

4.17 Resum dels modes d'adreçament principals del 6502

Cada instrucció per al 6502 és d'un byte, seguida de zero o més operands.

Mode d'adreçament immediat
Amb el mode d'adreçament immediat, després de l'operand, és el valor i no una adreça de memòria. El valor ha d'anar precedit de #. Si el valor és en hexadecimal, el '#' ha d'anar seguit de '$'. Les instruccions d'adreçament immediates per al 65C02 són: ADC, AND, BIT, CMP, CPX, CPY, EOR, LDA, LDX, LDY, ORA, SBC. El lector ha de consultar la documentació del 65C02 µP per saber com utilitzar les instruccions que s'enumeren aquí i que no s'expliquen en aquest capítol. Una instrucció d'exemple és:

LDA # $77

Mode d'adreçament absolut
En el mode d'adreçament absolut, hi ha un operand. Aquest operand és l'adreça del valor a la memòria (normalment en hexadecimal o una etiqueta). Hi ha 64K 10 = 65,536 10 adreces de memòria per a 6502 µP. Normalment, el valor d'un byte es troba en una d'aquestes adreces. Les instruccions d'adreçament absolutes per al 65C02 són: ADC, AND, ASL, BIT, CMP, CPX, CPY, DEC, EOR, INC, JMP, JSR, LDA, LDX, LDY, LSR, ORA, ROL, ROR, SBC, STA , STX, STY, STZ, TRB, TSB. El lector ha de consultar la documentació del 65C02 µP per saber com utilitzar les instruccions que s'enumeren aquí, així com per a la resta de modes d'adreçament que no s'expliquen en aquest capítol. Una instrucció d'exemple és:

SÓN 1234 $

Mode d'adreçament implícit
En el mode d'adreçament implícit, no hi ha cap operand. Qualsevol registre µP implicat està implicat per la instrucció. Les instruccions d'adreçament implícites per al 65C02 són: BRK, CLC, CLD, CLI, CLV, DEX, DEY, INX, INY, NOP, PHA, PHP, PHX, PHY, PLA, PLP, PLX, PLY, RTI, RTS, SEC , SED, SEI, TAX, TAY, TSX, TXA, TXS, TYA. Una instrucció d'exemple és:

DEX: Disminueix el registre X en una unitat.

Mode d'adreçament relatiu
El mode d'adreçament relatiu només tracta les instruccions de la branca. En el mode d'adreçament relatiu, només hi ha un operand. És un valor a partir de -128 10 a +127 10 . Aquest valor s'anomena desplaçament. En funció del signe, aquest valor s'afegeix o es resta de la següent instrucció del comptador de programes per donar lloc a l'adreça de la següent instrucció prevista. Les instruccions del mode d'adreça relativa són: BCC, BCS, BEQ, BMI, BNE, BPL, BRA, BVC, BVS. Els exemples d'instruccions són:

BNE $7F : (sucursal si Z = 0 al registre d'estat, P)

Que afegeix 127 al comptador del programa actual (adreça a executar) i comença a executar la instrucció en aquesta adreça. De la mateixa manera:

BEQ $F9 : (sucursal si Z = : al registre d'estat, P)

Que afegeix un -7 al comptador del programa actual i comença l'execució a la nova adreça del comptador del programa. L'operand és un nombre de complement a dos.

Adreçament indexat absolut
En l'adreçament d'índex absolut, el contingut del registre X o Y s'afegeix a l'adreça absoluta donada (entre $0000 i $FFFF, és a dir, des de 0). 10 al 65536 10 ) per tenir l'adreça real. Aquesta adreça absoluta donada s'anomena adreça base. Si s'utilitza el registre X, la instrucció de muntatge és una cosa així:

LDA $ C453,X

Si s'utilitza el registre Y, és una cosa com:

LDA $C453,I

El valor del registre X o Y s'anomena valor de recompte o d'índex i pot ser des de $ 00 (0 10 ) a $FF (250 10 ). No s'anomena compensació.

Les instruccions d'adreçament d'índex absolut són: ADC, AND, ASL (només X), BIT (amb acumulador i memòria, només amb X), CMP, DEC (només memòria i X), EOR, INC (només memòria i X), LDA , LDX, LDY, LSR (només X), ORA, ROL (només X), ROR (només X), SBC, STA, STZ (només X).

Adreçament indirecte absolut
Això només s'utilitza amb la instrucció de salt. Amb això, l'adreça absoluta donada té una adreça de punter. L'adreça del punter consta de dos bytes. El punter de dos bytes apunta a (és l'adreça de) el valor del byte de destinació a la memòria. Per tant, la instrucció del llenguatge ensamblador és:

JMP (3456 $)

Amb els parèntesis, i $13 es troba a la ubicació de l'adreça de $3456 mentre que $EB és a la ubicació de l'adreça de $3457 (= $3456 + 1). Aleshores, l'adreça de destinació és $13EB i $13EB és el punter. El $3456 absolut està entre parèntesis a la instrucció on 34 és el byte inferior i 56 és el byte més alt.

4.18 Creació d'una cadena amb el llenguatge assemblador 6502 µP

Com es demostra al capítol següent, després de crear un fitxer a la memòria, el fitxer es pot desar al disc. Cal donar un nom al fitxer. El nom és un exemple de cadena. Hi ha molts altres exemples de cadenes en programació.

Hi ha dues maneres principals de crear una cadena de codis ASCII. De totes dues maneres, tots els codis ASCII (caràcters) prenen ubicacions de bytes consecutives a la memòria. En una de les maneres, aquesta seqüència de bytes està precedida d'un byte enter que és la longitud (nombre de caràcters) de la seqüència (cadena). D'altra manera, la seqüència de caràcters és succeïda (seguida immediatament) pel byte nul que és 00 16 , és a dir, $00. La longitud de la cadena (nombre de caràcters) no s'indica d'aquesta altra manera. El caràcter nul no s'utilitza de la primera manera.

Per exemple, considereu el 'T'estimo!' cadena sense cometes. La longitud aquí és d'11; un espai compta com un byte ASCII (caràcter). Suposem que la cadena s'ha de col·locar a la memòria amb el primer caràcter a l'adreça $0300.

La taula següent mostra la configuració de la memòria de cadena quan el primer byte és 11 10 = 0B 16 :

La taula següent mostra la configuració de memòria de cadena quan el primer byte és 'I' i l'últim byte és nul ($00):

La següent instrucció es pot utilitzar per començar a crear la cadena:

COSTEEN 0300 $

Suposem que el primer byte es troba a l'acumulador que s'ha d'enviar a la ubicació de l'adreça de $0300. Aquesta instrucció és certa per als dos casos (ambdós tipus de cadenes).

Després d'ajustar tots els caràcters a les cel·les de memòria, un per un, la cadena es pot llegir mitjançant un bucle. En el primer cas, es llegeix el nombre de caràcters després de la longitud. Per al segon cas, els caràcters es llegeixen des de 'I' fins que es compleix el caràcter nul que és 'Nul'.

4.19 Creació d'una matriu amb el llenguatge assemblador 6502 µP

Una matriu d'enters d'un sol byte consisteix en ubicacions consecutives de bytes de memòria amb els nombres enters. Aleshores, hi ha un punter que apunta a la ubicació del primer nombre enter. Per tant, una matriu de nombres enters consta de dues parts: el punter i la sèrie d'ubicacions.

Per a una matriu de cadenes, cada cadena pot estar en un lloc diferent de la memòria. Aleshores, hi ha ubicacions de memòria consecutives amb punters on cada punter apunta a la primera ubicació de cada cadena. Un punter en aquest cas consta de dos bytes. Si una cadena comença amb la seva longitud, el punter corresponent apunta a la ubicació d'aquesta longitud. Si una cadena no comença amb la seva longitud sinó que acaba amb un caràcter nul, el punter corresponent apunta a la ubicació del primer caràcter de la cadena. I hi ha un punter que apunta a l'adreça de byte inferior del primer punter de punters consecutius. Per tant, una matriu de cadenes consta de tres parts: les cadenes en diferents llocs de la memòria, els punters consecutius corresponents i el punter al primer punter dels punters consecutius.

4.20 Problemes

Es recomana al lector que resolgui tots els problemes d'un capítol abans de passar al capítol següent.

  1. Escriu un programa de llenguatge ensamblador que comenci a $0200 per al 6502 µP i afegeixi els números sense signar de 2A94 H (afegiu) a 2ABF H (augend). Deixeu que les entrades i les sortides estiguin a la memòria. A més, elaboreu manualment el document del programa muntat.
  2. Escriu un programa de llenguatge ensamblador que comenci a $0200 per al 6502 µP i resta els nombres sense signe de 1569 H (substraend) de 2ABF H (minuend). Deixeu que les entrades i sortides estiguin a la memòria. A més, elaboreu manualment el document del programa muntat.
  3. Escriu un programa de llenguatge ensamblador per al 6502 µP que compti des de $00 fins a $09 mitjançant un bucle. El programa hauria de començar a $ 0200. A més, elaboreu manualment el document del programa muntat.
  4. Escriu un programa de llenguatge ensamblador que comenci a $0200 per al 6502 µP. El programa té dues subrutines. La primera subrutina afegeix els números sense signar de 0203 H (augend) i 0102H (addend). La segona subrutina suma la suma de la primera subrutina que és 0305H a 0006 H (augend). El resultat final s'emmagatzema a la memòria. Truqueu la primera subrutina que és FSTSUB i la segona subrutina que és SECSUB. Deixeu que les entrades i sortides estiguin a la memòria. A més, elaboreu manualment el document del programa muntat per a tot el programa.
  5. Tenint en compte que an IRQ El gestor afegeix $02 a $01 a l'acumulador com a gestió bàsica mentre NMI s'emet i la gestió bàsica per NMI afegeix $ 05 a $ 04 a l'acumulador, escriu un llenguatge ensamblador per als dos gestors incloses les seves trucades. La crida al IRQ El gestor hauria d'estar a l'adreça de $0200. El IRQ El gestor hauria de començar a l'adreça de $0300. El NMI El gestor hauria de començar a l'adreça de $0400. El resultat de la IRQ s'ha de posar a l'adreça de $0500, i el resultat del NMI s'ha de posar a l'adreça de $0501.
  6. Expliqueu breument com s'utilitza la instrucció BRK per produir la interrupció de programari en un ordinador 65C02.
  7. Elabora una taula que compare i contrasti una subrutina normal amb una rutina de servei d'interrupció.
  8. Expliqueu breument els modes d'adreçament principals del 65C02 µP donats els exemples d'instruccions en llenguatge ensamblador.
  9. a) Escriu un programa de llenguatge màquina 6502 per posar el 'T'estimo!' cadena de codis ASCII a la memòria, començant per l'adreça $0300 amb la longitud de la cadena. El programa hauria de començar a l'adreça $0200. Obteniu cada caràcter de l'acumulador un per un, suposant que s'envien allà, per alguna subrutina. A més, munta el programa a mà. (Si necessiteu saber els codis ASCII de 'T'estimo!'. Aquí estan: 'I':49 16 , espai: 20 16 , 'l': 6C 16 , 'o':6F 16 , 'en':76 16 , 'e':65, 'y':79 16 , 'en':75 16 , i ‘!’:21 16 (Nota: cada codi ocupa 1 byte).
    b) Escriu un programa de llenguatge màquina 6502 per posar el 'T'estimo!' cadena de codis ASCII a la memòria, començant per l'adreça $ 0300 sense la longitud de la cadena però acabant en 00 16 . El programa hauria de començar a l'adreça $0200. Obteniu cada caràcter de l'acumulador, suposant que s'envien allà, un a un, per alguna subrutina. A més, munta el programa a mà.