Le 68000 possède une cinquantaine d'instructions. Chaque instruction, à quelques exceptions près, travaille sur des octets, des mots courts ou longs et dans leur grande majorité utilise les différents modes d'adressage.
Les instructions de base concernent le transfert de données, les opérations arithmétiques et logiques, le contrôle de programme et sous programme.
Transfert de données:
Les opérations de transfert de données sont couramment utilisées dans un programme (l'instruction MOVE peut représenter jusqu'a 75% d'un programme). L'instruction MOVE est l'instruction générique du 68000. On la retrouve sous diverses variantes et syntaxes. Ces instructions ont des particularités très intéressantes et permettent de simplifier efficacement un programme.
Instruction |
Syntaxe |
Taille opérande |
Opération |
MOVE |
MOVE AEs, AEd |
B, W, L |
(AE)s --> AEd |
MOVEA |
MOVE AE, An |
W, L |
(AE) --> An |
MOVEM |
MOVEM ListR, AE MOVEM AE, ListR |
W, L |
Dn/An --> AE ou (AE) --> Dn/An |
MOVEQ |
MOVEQ #XX, Dn |
B |
xx --> Dn |
-MOVEQ (Move Quick) permet de transférer rapidement une donnée sur 8 bits vers un registre de données.
-MOVEM (Move Multiple), permet de transférer en une seule opération le contenu d'une liste de registres vers une adresse effective (adresse mémoire ou registre A7) ou l'inverse:
exemple MOVEM.L D0-D7/A0-A6,-(A7) sauvegarde le contenu des registres D0 à D7 et A0 à A6 sur la pile.
- Movea (Move address) permet de transférer le contenu d'une adresse effective vers un registre d'adresse.
Opérations arithmétiques , logiques:
On retrouve les opérations arithmétiques de base, addition (ADD), soustraction (SUB), multiplication signée et non signée (MULS, MULU), division signée et non signée (DIVS, DIVU).
Instruction |
Syntaxe |
Taille opérande |
Opération |
ADD |
ADD AE, Dn |
B, W, L |
(AE)+Dn -> Dn |
ADDA |
ADDA AE, An |
W, L |
(AE)+An --> An |
ADDI |
ADDI #XXX, AE |
B, W, L |
XXXX+(AE) --> AE |
ADDQ |
ADDQ #XX, AE |
B |
xx+(AE) --> AE |
ADDX |
ADDX Dy, Dx |
B, W, L |
Dy+Dx --> Dx |
MULU ou MULS |
MULU (AE), Dn |
W x W-->L |
(AE).Dn --> Dn |
DIVU ou DIVS |
DIVU (AE), Dn |
L/W |
Dn÷(AE) --> Dn |
L'instruction ADDX est utile pour effectuer une addition de nombres de 64 bits par exemple. On fait d'abord dans ce cas une addition des 32 bits de poids faible qui peut générer une retenue. Retenue qui est prise en compte par ADDX lorsqu'on effectue ensuite l'addition des 32 bits de poids fort (voir exercice).
Note: les instructions ADD et SUB ont les mêmes variantes
Instruction |
Syntaxe |
Taille de opérande |
Opération |
AND |
AND (AE), Dn ou Dn, AE |
B, W, L |
(AE) & Dn --> Dn |
ANDI |
ANDI #XXX, AE |
B, W, L |
XXX & (AE) --> AE |
OR |
OR (AE), Dn |
B, W, L |
(AE) OU Dn --> Dn |
ORI |
ORI #XXX, AE |
B, W, L |
XXX OU (AE) --> AE |
EOR |
EOR Dn, AE |
B, W, L |
(AE) OUex Dn --> AE |
EORI |
EORI #XXX, AE |
B, W, L |
XXX OUex (AE) --> AE |
NOT |
NOT (AE) |
B, W, L |
Complement a Un de (AE) --> AE |
AE=adresse effective, s=source, d=destination
Les instructions AND, OR, EOR sont des opérations qui s'effectuent bit à bit entre deux opérandes. On utilise par exemple l'instruction ANDI pour forcer des bits particuliers d'une mémoire à 0 et l'instruction ORI pour forcer des bits particuliers d'une mémoire à 1:
-si on veut Adresse=00xxxxxx, on remplace les x par 1 (le 1 est l'élément neutre de la fonction ET) et on fait ANDI.B # $ 3F, Adresse.
-si on veut par contre Adresse=11xxxxxx, on remplace les x par 0 (le 0 est l'élément neutre de la fonction OU) et on fait ORI.B # $ C0, Adresse.
Contrôle de programmes et sous programmes:
Le 68000 dispose d'une série d'instructions qui permettent de modifier le comportement séquentiel de l'exécution d'un programme dû à l'auto incrémentation du compteur programme. Ces instructions modifient en fait le compteur programme (PC) du microprocesseur. On distingue les instructions de sauts ou branchements inconditionnels (JMP, BRA) et conditionnels (Bcc, DBcc) qui ne permettent pas en générale de revenir dans le programme principal et les instructions d'appel à un sous programme (JSR, BSR) qui permettent le retour au programme principal à condition que ce sous programme soit terminé par les instructions RTS (retour de sous programme).
Instruction |
Description |
Opération |
Bcc |
Branchement conditionnelle |
si condition vraie alors PC + d8-16--> PC Sinon PC + 2--> PC |
DBcc |
Test condition, décrémentation et branchement |
Si condition fausse alors Dn-1-->Dn et si Dn≠-1 alors PC + d8-16--> PC Sinon PC + 2--> PC |
BRA |
Branchement inconditionnelle |
PC + d8-16--> PC |
BSR |
Branchement sous-routine |
sauvegarde de PC sur la pile et PC + d8-16--> PC |
JMP |
Saut |
Adresse destination--> PC |
JSR |
Saut sous-routine |
sauvegarde de PC sur A7 et Adresse destination --> PC |
RTS |
Retour de sous-programme |
(A7)+ --> PC |
Dans les instructions Bcc et DBcc, cc désigne des conditions telles que : CC (Carry Clear), NE (Nor Equal), GT (Greater Than), etc... Ces instructions testent une combinaison logique des codes conditions (5 bits de poids faible du SR).
Par exemple BLS teste C+Z (Carry et Zéro); le branchement aura lieu si la carry et le zéro sont vrais tous les deux en même temps.
Au niveau du 68000 c'est le registre d'adresse A7 qui joue le rôle de pointeur de pile. La pile est en fait une zone mémoire réservée servant à stocker temporairement certaines données. Sa structure est de type LIFO (Last In Fist Out), c'est-à-dire dernier entré, premier sorti. Son adresse de base est initialisée au démarrage du système.
Le registre A7 contient toujours l'adresse de la dernière valeur enregistrée sur la pile et le stockage d'une valeur sur cette pile se fait en décrémentant les adresses.
L'écriture d'une valeur sur la pile se fait à l'aide de l'instruction PEA (Push Effective Address) selon la syntaxe: PEA adresse , équivalente à MOVE.L #adresse , -(A7) ; adressage indirect sur le registre A7 avec pré-décrémentation.
Exemple: PEA $3F00 ou MOVE.L #$3F00, -(A7) |
Avant:
A7=$4FF89DCC, $4FF89DC8=$FFFFFFFF Après: A7=$4FF89DCC-4=$4FF89DC8 $4FF89DC8=$00003F00 |
La valeur $3F00 est copiée à l'adresse $4FF89DCC-4=$4FF89DC8. Le contenu du registre A7 est modifié et contient désormais la valeur $4FF89DC8. |
La lecture d'une valeur sur la pile se fait au moyen d'un adressage indirect avec post-incrémentation sur le registre A7.
Exemple: MOVE.L (A7)+, D1 |
Avant:
A7=$4FF89DC8, $4FF89DC8=$00003F00 D1=$FFFFFFFF Après: D1=$00003F00 A7=$4FF89DC8+4=$4FF89DCC |
Le mot de 32 bits présent en haut de la pile à l'adresse $4FF89DC8 est copiée dans le registre de donnée D1, puis le contenu du registre A7 est modifié (incrémenté de 4) pour contenir au final la valeur $4FF89DCC. |
Les deux modes d'écriture ou de lecture de la pile présentés ci-dessus constituent une gestion automatique de la pile car le pointeur de pile est modifie par le 68000 lui-même. Cependant il peut arriver que dans certains cas, il soit nécessaire de lire ou d'écrire sur la pile sans la modifier. On utilise alors un mode d'adressage adéquat: adressage indirect avec déplacement par rapport au registre A7.
Exemple: MOVE.W $36(A7), D1 |
Avant:
A7=$4FF89DCC, $4FF89E02=$24503FD8 D1=$FFFFFFFF Après: D1=$FFFF2450 A7=$4FF89DCC |
Le mot de 16 bits situé à 36 octets de l'adresse $4FF89DCC est copiée dans le registre de donnée D1, le contenu du registre A7 restant inchangé. |