Architecture et programmation des MCU 8051 pour le rétro-ingénierie 2
Chapitre 3 : Le jeu d'instructions 8051
Introduction
Écrire des programmes pour microcontrôleurs consiste essentiellement à émettre des instructions (commandes) dans une séquence d'exécution spécifique pour accomplir des tâches désignées. Le matériel électronique ne peut pas interpréter une logique lisible par l'homme telle que « Si le bouton est enfoncé, allume la lumière ». Les développeurs doivent plutôt utiliser une série de commandes simples et strictement définies, reconnaissables par le décodeur interne du MCU. L'ensemble complet de ces commandes valides est appelé le jeu d'instructions. Tous les microcontrôleurs compatibles 8051 disposent d'un total de 255 instructions distinctes, ce qui signifie qu'il existe 255 mots machine uniques disponibles pour le développement de programmes.
À première vue, mémoriser ce grand ensemble de codes opérationnels symboliques semble intimidant. Cependant, la charge d'apprentissage réelle est bien plus légère qu'il n'y paraît. De nombreuses instructions comptent comme des entrées séparées alors qu'elles exécutent des opérations sous-jacentes identiques, ne laissant que 111 commandes fonctionnellement uniques. Par exemple, ADD A,R0, ADD A,R1, ..., ADD A,R7 effectuent toutes la même opération d'addition entre l'accumulateur et un registre de travail. Comme il existe huit registres de travail, chaque variante est répertoriée comme une entrée d'instruction distincte. Étant donné que toutes les instructions n'implémentent que 53 opérations principales (addition, soustraction, copie de données, etc.) et que la plupart de ces opérations sont rarement utilisées dans les projets pratiques, les développeurs n'ont besoin de maîtriser qu'environ 20 à 30 mnémoniques, ce qui est très gérable.
Au-delà de l'exécution fonctionnelle du programme, le jeu d'instructions constitue la première ligne de défense contre l'accès non autorisé au firmware. La plupart des systèmes embarqués s'appuient sur des mécanismes de bits de verrouillage pour bloquer la lecture externe de la mémoire flash ou EEPROM interne. Néanmoins, une compréhension approfondie du comportement à l'exécution de chaque instruction est essentielle à la fois pour écrire un firmware de production sécurisé et pour mener un rétro-ingénierie légitime afin de récupérer du code source perdu. Les attaquants exploitent fréquemment des comportements spécifiques d'instructions pour contourner la protection par verrouillage, en utilisant l'injection de fautes, l'analyse temporelle et d'autres techniques par canaux auxiliaires pour déclencher un état de déverrouillage. Dans de nombreux scénarios d'attaque, le décapage physique de la puce associé à une micro-sondage permet de lire directement les bits de fusibles de sécurité, permettant ainsi des vidages binaires complets du firmware stocké. La capacité à répliquer la fonctionnalité complète d'un dispositif repose souvent sur une extraction réussie du firmware via ces méthodes, faisant de la récupération de firmware une compétence essentielle dans la recherche en sécurité embarquée.
3.1 Types d'instructions
Toutes les instructions sont classées en cinq groupes principaux selon les opérations qu'elles effectuent :
- Instructions arithmétiques
- Instructions de branchement
- Instructions de transfert de données
- Instructions logiques
- Instructions orientées bit
Le premier segment de chaque instruction est appelé un mnémonique, qui représente l'opération principale à exécuter (copie de données, addition arithmétique, logique bit à bit, etc.). Les mnémoniques sont des abréviations du nom complet de chaque opération matérielle. Des exemples de définitions sont donnés ci-dessous :
INC R1 – Incrémente la valeur stockée dans le registre R1 de un ;
LJMP LAB5 – Effectue un saut inconditionnel long vers l'adresse mémoire étiquetée LAB5 ;
JNZ LOOP – Saute vers l'adresse étiquetée LOOP si la valeur de l'accumulateur est non nulle ;
Le second segment d'une instruction est l'opérande, séparé du mnémonique par au moins un espace, et il définit les cibles de données traitées par l'opération. Certaines instructions ne comportent aucun opérande, d'autres en incluent un, deux ou trois. Les opérandes multiples au sein d'une même instruction sont séparés par des virgules. Exemples :
RET – Retourne le flux d'exécution d'une sous-routine ;
JZ TEMP – Saute vers l'adresse étiquetée TEMP si la valeur de l'accumulateur est nulle ;
ADD A,R3 – Ajoute la valeur du registre R3 à l'accumulateur ;
CJNE A,#20,LOOP – Compare l'accumulateur avec la constante immédiate 20 ; saute vers LOOP si les deux valeurs sont inégales ;
Chaque catégorie d'instructions joue un rôle distinct dans la posture de sécurité globale du dispositif. Les instructions orientées bit manipulent directement les bits de verrouillage et autres fusibles de configuration de sécurité. Les opcodes de transfert de données tels que MOVC lisent la mémoire programme, et ces instructions renvoient des données erronées lorsque la protection par bit de verrouillage est active. Les flux de travail de rétro-ingénierie se concentrent souvent sur l'identification des séquences d'instructions qui valident l'état du verrou, puis tentent de sauter ces branches de validation via des glitches d'horloge ou une altération du compteur de programme. Dans certains cas, la récupération d'un MCU verrouillé et irrécupérable nécessite de localiser des portes dérobées de bootloader cachées qui utilisent des instructions de branchement spécifiques pour activer la lecture complète de la mémoire.
Instructions arithmétiques
Les instructions arithmétiques exécutent des opérations mathématiques fondamentales incluant l'addition, la soustraction, la multiplication et la division. Une fois le calcul terminé, la valeur résultante est stockée dans le premier opérande spécifié. Exemple :
ADD A,R1 – La somme de l'accumulateur A et du registre R1 est sauvegardée dans le registre accumulateur.
| Instructions arithmétiques |
| Mnémonique |
Description |
Octet |
Cycle |
| ADD A,Rn |
Ajouter le contenu du registre de travail à l'accumulateur |
1 |
1 |
| ADD A,direct |
Ajouter un octet d'adresse directe à l'accumulateur |
2 |
2 |
| ADD A,@Ri |
Ajouter un octet RAM interne adressé indirectement à l'accumulateur |
1 |
2 |
| ADD A,#data |
Ajouter une constante immédiate à l'accumulateur |
2 |
2 |
| ADDC A,Rn |
Ajouter le registre à l'accumulateur avec retenue entrante |
1 |
1 |
| ADDC A,direct |
Ajouter un octet direct à l'accumulateur avec retenue entrante |
2 |
2 |
| ADDC A,@Ri |
Ajouter un octet RAM indirect à l'accumulateur avec retenue entrante |
1 |
2 |
| ADDC A,#data |
Ajouter une constante immédiate à l'accumulateur avec retenue entrante |
2 |
2 |
| SUBB A,Rn |
Soustraire le registre de l'accumulateur avec emprunt entrant |
1 |
1 |
| SUBB A,direct |
Soustraire un octet direct de l'accumulateur avec emprunt entrant |
2 |
2 |
| SUBB A,@Ri |
Soustraire un octet RAM indirect de l'accumulateur avec emprunt entrant |
1 |
2 |
| SUBB A,#data |
Soustraire une constante immédiate de l'accumulateur avec emprunt entrant |
2 |
2 |
| INC A |
Incrémenter l'accumulateur de un |
1 |
1 |
| INC Rn |
Incrémenter le registre de travail de un |
1 |
2 |
| INC Rx |
Incrémenter l'octet d'adresse directe de un |
2 |
3 |
| INC @Ri |
Incrémenter l'octet RAM indirect de un |
1 |
3 |
| DEC A |
Décrémenter l'accumulateur de un |
1 |
1 |
| DEC Rn |
Décrémenter le registre de travail de un |
1 |
1 |
| DEC Rx |
Décrémenter l'octet d'adresse directe de un |
1 |
2 |
| DEC @Ri |
Décrémenter l'octet RAM indirect de un |
2 |
3 |
| INC DPTR |
Incrémenter le pointeur de données 16 bits de un |
1 |
3 |
| MUL AB |
Multiplier l'accumulateur A par le registre B |
1 |
5 |
| DIV AB |
Diviser l'accumulateur A par le registre B |
1 |
5 |
| DA A |
Ajustement décimal de l'accumulateur pour les résultats BCD |
1 |
1 |
Les instructions arithmétiques servent à plus que de simples tâches de traitement de données ; elles font partie intégrante des routines de vérification de somme de contrôle et de chiffrement qui valident l'intégrité du firmware. Les attaquants qui peuvent corrompre les résultats d'addition ou de soustraction via des glitches de tension peuvent contourner les contrôles de sécurité qui comparent les sommes de contrôle calculées aux valeurs de référence stockées. Cette manipulation peut déclencher une séquence de déverrouillage même lorsque le fusible de verrouillage reste activé. Pour les flux de travail d'extraction de firmware, une connaissance approfondie du comportement arithmétique de l'UAL permet de concevoir des attaques par injection de fautes ciblées conçues pour sauter la logique de validation du verrouillage. De plus, les indicateurs d'état de retenue (C) et de débordement (OV) sont des cibles d'attaque fréquentes : des glitches sur l'unité arithmétique et logique peuvent forcer des états de drapeaux incorrects et contourner les vérifications de comparaison d'état de verrouillage critiques.
Instructions de branchement
Les instructions de branchement se divisent en deux catégories distinctes :
Instructions de saut inconditionnel : Lors de l'exécution, le CPU saute immédiatement vers une nouvelle adresse mémoire et reprend le flux du programme à partir de cet endroit sans condition préalable.
Instructions de saut conditionnel : Un saut vers une adresse alternative du programme n'est exécuté que si une condition logique spécifiée est vraie. Si la condition échoue, le CPU continue séquentiellement vers l'instruction suivante en mémoire.
| Instructions de branchement |
| Mnémonique |
Description |
Octet |
Cycle |
| ACALL addr11 |
Appel de sous-routine absolu dans une page de 2 Ko |
2 |
6 |
| LCALL addr16 |
Appel de sous-routine long sur 64 Ko |
3 |
6 |
| RET |
Retour d'une sous-routine standard |
1 |
4 |
| RETI |
Retour d'une routine d'interruption |
1 |
4 |
| AJMP addr11 |
Saut absolu dans la page 2 Ko courante |
2 |
3 |
| LJMP addr16 |
Saut long vers toute adresse 64 Ko |
3 |
4 |
| SJMP rel |
Saut relatif court (-128 à +127) |
2 |
3 |
| JC rel |
Saut court si drapeau de retenue C est à 1 |
2 |
3 |
| JNC rel |
Saut court si drapeau de retenue C est à 0 |
2 |
3 |
| JB bit,rel |
Saut court si le bit direct spécifié est 1 |
3 |
4 |
| JBC bit,rel |
Saut si bit direct à 1, puis efface le bit (saut court) |
3 |
4 |
| JMP @A+DPTR |
Saut indirect indexé utilisant A + DPTR |
1 |
2 |
| JZ rel |
Saut court si accumulateur nul |
2 |
3 |
| JNZ rel |
Saut court si accumulateur non nul |
2 |
3 |
| CJNE A,direct,rel |
Comparer accumulateur et octet direct ; saut court si inégaux |
3 |
4 |
| CJNE A,#data,rel |
Comparer accumulateur et constante ; saut court si inégaux |
3 |
4 |
| CJNE Rn,#data,rel |
Comparer registre de travail et constante ; saut court si inégaux |
3 |
4 |
| CJNE @Ri,#data,rel |
Comparer octet RAM indirect et constante ; saut court si inégaux |
3 |
4 |
| DJNZ Rn,rel |
Décrémenter registre, saut court si résultat non nul |
2 |
3 |
| DJNZ Rx,rel |
Décrémenter octet direct, saut court si résultat non nul |
3 |
4 |
| NOP |
Aucune opération (occupation de cycle d'horloge) |
1 |
1 |
Les instructions de branchement forment le cœur de la logique conditionnelle du programme, y compris toutes les routines de validation de sécurité critiques. L'opcode JB, par exemple, est largement utilisé pour tester l'état du fusible de verrouillage. Si le bit de verrouillage est activé, le programme saute vers une sous-routine de sécurité qui désactive les interfaces de débogage et bloque la lecture mémoire. Les attaquants peuvent cibler l'exécution de JB avec des glitches d'horloge pour forcer le matériel à traiter un bit de verrouillage activé comme désactivé, déverrouillant complètement le microcontrôleur. De même, les instructions CJNE alimentent les boucles de vérification de mot de passe ; l'injection d'une faute de timing ou de tension en pleine comparaison peut rediriger le compteur de programme vers une adresse non prévue, exposant le code firmware protégé. Dans les flux de travail de rétro-ingénierie, la cartographie complète du graphe de flux de contrôle des branchements est obligatoire pour localiser les chemins de déverrouillage légitimes et patcher le firmware binaire pour la récupération de données.
Instructions de transfert de données
Les opcodes de transfert de données copient des valeurs d'un registre ou d'un emplacement mémoire vers un autre, sans modifier les données sources. Les instructions portant le suffixe « X » (MOVX) facilitent les échanges de données avec les espaces mémoire RAM externes.
| Instructions de transfert de données |
| Mnémonique |
Description |
Octet |
Cycle |
| MOV A,Rn |
Copier la valeur du registre de travail dans l'accumulateur |
1 |
1 |
| MOV A,direct |
Copier l'octet d'adresse directe dans l'accumulateur |
2 |
2 |
| MOV A,@Ri |
Copier l'octet RAM indirect dans l'accumulateur |
1 |
2 |
| MOV A,#data |
Charger une constante immédiate dans l'accumulateur |
2 |
2 |
| MOV Rn,A |
Copier l'accumulateur dans le registre de travail |
1 |
2 |
| MOV Rn,direct |
Copier l'octet direct dans le registre de travail |
2 |
4 |
| MOV Rn,#data |
Charger une constante immédiate dans le registre de travail |
2 |
2 |
| MOV direct,A |
Copier l'accumulateur dans l'octet direct |
2 |
3 |
| MOV direct,Rn |
Copier le registre de travail dans l'octet direct |
2 |
3 |
| MOV direct,direct |
Copier un octet direct vers un autre octet direct |
3 |
4 |
| MOV direct,@Ri |
Copier l'octet RAM indirect vers l'octet direct |
2 |
4 |
| MOV direct,#data |
Charger une constante immédiate dans l'octet direct |
3 |
3 |
| MOV @Ri,A |
Copier l'accumulateur dans l'octet RAM indirect |
1 |
3 |
| MOV @Ri,direct |
Copier l'octet direct vers l'emplacement RAM indirect |
2 |
5 |
| MOV @Ri,#data |
Charger une constante immédiate dans l'octet RAM indirect |
2 |
3 |
| MOV DPTR,#data |
Charger une constante 16 bits dans le pointeur de données |
3 |
3 |
| MOVC A,@A+DPTR |
Lire un octet de mémoire programme à l'offset A+DPTR |
1 |
3 |
| MOVC A,@A+PC |
Lire un octet de mémoire programme à l'offset A+PC |
1 |
3 |
| MOVX A,@Ri |
Lire un octet RAM externe adressé sur 8 bits dans l'accumulateur |
1 |
3-10 |
| MOVX A,@DPTR |
Lire un octet RAM externe adressé sur 16 bits dans l'accumulateur |
1 |
3-10 |
| MOVX @Ri,A |
Écrire l'accumulateur dans la RAM externe adresse 8 bits |
1 |
4-11 |
| MOVX @DPTR,A |
Écrire l'accumulateur dans la RAM externe adresse 16 bits |
1 |
4-11 |
| PUSH direct |
Empiler l'octet direct sur la pile système |
2 |
4 |
| POP direct |
Dépiler la valeur du sommet de pile dans l'octet direct |
2 |
3 |
| XCH A,Rn |
Échanger les octets complets entre accumulateur et registre de travail |
1 |
2 |
| XCH A,direct |
Échanger les octets complets entre accumulateur et octet direct |
2 |
3 |
| XCH A,@Ri |
Échanger les octets complets entre accumulateur et octet RAM indirect |
1 |
3 |
| XCHD A,@Ri |
Échanger uniquement les 4 bits de poids faible de l'accumulateur et de l'octet RAM indirect |
1 |
3 |
Les instructions de transfert de données apparaissent le plus fréquemment dans tous les firmwares embarqués et représentent simultanément des surfaces d'attaque critiques pour les exploits de sécurité. Les opcodes MOVC sont exclusivement conçus pour lire la mémoire programme ; lorsque la protection par bit de verrouillage est active, ces instructions renvoient des données corrompues. Cependant, l'application de glitches de tension précis pendant l'exécution de MOVC peut forcer le MCU à produire les octets de code originaux non modifiés, permettant des attaques de vidage flash octet par octet largement utilisées en rétro-ingénierie par canaux auxiliaires. Les instructions MOVX accèdent aux bus mémoire externes non chiffrés, que les adversaires peuvent surveiller passivement avec des analyseurs logiques pour dupliquer complètement le firmware sans altérer les fusibles de sécurité internes. Pour le stockage EEPROM interne, les variantes MOV direct permettent un accès en lecture/écriture aux registres de fonctions spéciales contrôlant l'état des fusibles de verrouillage ; des interfaces de débogage non fermées permettent aux attaquants d'utiliser de simples séquences MOV pour déverrouiller la puce et effectuer une extraction complète de la mémoire. PUSH et POP gèrent la mémoire de pile, une cible courante pour les exploits de débordement de pile qui écrasent les adresses de retour et redirigent l'exécution vers des sous-routines de déverrouillage malveillantes. Lors de la récupération forensique de matériel embarqué verrouillé, les analystes tracent toutes les séquences d'instructions MOV pour localiser les portes dérobées non documentées du fabricant, intentionnellement laissées pour le reflashage en usine.
Instructions logiques
Les instructions logiques exécutent des opérations logiques bit à bit sur les positions de bits correspondantes de deux opérandes octets, stockant le résultat final calculé dans le premier registre opérande.
| Instructions logiques |
| Mnémonique |
Description |
Octet |
Cycle |
| ANL A,Rn |
ET bit à bit du registre de travail avec l'accumulateur |
1 |
1 |
| ANL A,direct |
ET bit à bit de l'octet direct avec l'accumulateur |
2 |
2 |
| ANL A,@Ri |
ET bit à bit de l'octet RAM indirect avec l'accumulateur |
1 |
2 |
| ANL A,#data |
ET bit à bit de la constante immédiate avec l'accumulateur |
2 |
2 |
| ANL direct,A |
ET bit à bit de l'accumulateur avec l'octet direct, stocke dans l'octet direct |
2 |
3 |
| ANL direct,#data |
ET bit à bit de la constante immédiate avec l'octet direct |
3 |
4 |
| ORL A,Rn |
OU bit à bit du registre de travail avec l'accumulateur |
1 |
1 |
| ORL A,direct |
OU bit à bit de l'octet direct avec l'accumulateur |
2 |
2 |
| ORL A,@Ri |
OU bit à bit de l'octet RAM indirect avec l'accumulateur |
1 |
2 |
| ORL direct,A |
OU bit à bit de l'accumulateur avec l'octet direct, stocke dans l'octet direct |
2 |
3 |
| ORL direct,#data |
OU bit à bit de la constante immédiate avec l'octet direct |
3 |
4 |
| XRL A,Rn |
OU exclusif bit à bit du registre de travail avec l'accumulateur |
1 |
1 |
| XRL A,direct |
OU exclusif bit à bit de l'octet direct avec l'accumulateur |
2 |
2 |
| XRL A,@Ri |
OU exclusif bit à bit de l'octet RAM indirect avec l'accumulateur |
1 |
2 |
| XRL A,#data |
OU exclusif bit à bit de la constante immédiate avec l'accumulateur |
2 |
2 |
| XRL direct,A |
OU exclusif bit à bit de l'accumulateur avec l'octet direct, stocke dans l'octet direct |
2 |
3 |
| XORL direct,#data |
OU exclusif bit à bit de la constante immédiate avec l'octet direct |
3 |
4 |
| CLR A |
Mettre tous les bits de l'accumulateur à 0 |
1 |
1 |
| CPL A |
Inverser bit à bit tous les bits de l'accumulateur |
1 |
1 |
| SWAP A |
Échanger le quartet haut et le quartet bas dans l'accumulateur |
1 |
1 |
| RL A |
Rotation à gauche des bits de l'accumulateur (sans retenue) |
1 |
1 |
| RLC A |
Rotation à gauche de l'accumulateur à travers le drapeau de retenue |
1 |
1 |
| RR A |
Rotation à droite des bits de l'accumulateur (sans retenue) |
1 |
1 |
| RRC A |
Rotation à droite de l'accumulateur à travers le drapeau de retenue |
1 |
1 |
Les instructions logiques bit à bit sont largement utilisées pour masquer et manipuler les fusibles de verrouillage et autres registres de configuration de sécurité critiques. Par exemple, les masques ANL peuvent effacer sélectivement des bits individuels dans les SFR de contrôle de sécurité, tandis que les masques ORL définissent des bits d'activation de fusibles spécifiques. Les attaquants capables d'injecter des fautes de timing ou de tension pendant l'exécution de ces opcodes logiques peuvent accidentellement basculer l'état du bit de verrouillage et déverrouiller complètement le microcontrôleur. De plus, les instructions OU exclusif XRL constituent la base des routines d'obfuscation de firmware et de chiffrement léger ; inverser l'opération de masquage XOR permet aux adversaires de récupérer les clés de sécurité en clair stockées dans la mémoire EEPROM. Pour les flux de travail d'extraction de firmware, une compréhension approfondie des opérations logiques bit à bit est indispensable pour déchiffrer les segments de code protégés avant d'initier des vidages mémoire binaires complets.
Instructions orientées bit
Les instructions orientées bit effectuent des opérations logiques analogues au groupe logique sur octets, mais elles opèrent exclusivement sur des emplacements de bits uniques plutôt que sur des octets complets.
| Instructions orientées bit |
| Mnémonique |
Description |
Octet |
Cycle |
| CLR C |
Effacer le drapeau de retenue (mettre à 0) |
1 |
1 |
| CLR bit |
Effacer un bit adressable direct (mettre à 0) |
2 |
3 |
| SETB C |
Mettre le drapeau de retenue à 1 |
1 |
1 |
| SETB bit |
Mettre un bit adressable direct à 1 |
2 |
3 |
| CPL C |
Inverser l'état du drapeau de retenue |
1 |
1 |
| CPL bit |
Inverser l'état d'un bit direct |
2 |
3 |
| ANL C,bit |
ET logique entre le bit direct et le drapeau de retenue, résultat dans C |
2 |
2 |
| ANL C,/bit |
ET logique entre le bit direct inversé et C, résultat dans C |
2 |
2 |
| ORL C,bit |
OU logique entre le bit direct et C, résultat dans C |
2 |
2 |
| ORL C,/bit |
OU logique entre le bit direct inversé et C, résultat dans C |
2 |
2 |
| MOV C,bit |
Copier l'état d'un bit direct dans le drapeau de retenue |
2 |
2 |
| MOV bit,C |
Copier l'état du drapeau de retenue dans un bit direct |
2 |
3 |
Les opcodes orientés bit représentent l'interface logicielle principale pour manipuler les fusibles de verrouillage et autres indicateurs de sécurité mono-bit. SETB et CLR peuvent modifier directement les valeurs d'état des fusibles de verrouillage, bien que la plupart des MCU dérivés 8051 modernes renforcent les protections matérielles pour rendre les registres de verrouillage en lecture seule pendant l'exécution normale. Des bogues logiciels critiques permettant un accès en écriture à ces registres de sécurité adressables par bit créent des vecteurs d'attaque de déverrouillage à distance pour les acteurs malveillants. L'instruction MOV C,bit lit l'état du fusible de verrouillage et transfère la valeur dans le drapeau de retenue, que les instructions conditionnelles JC/JNC évaluent ensuite pour appliquer les restrictions d'accès mémoire. Cette séquence d'instructions de vérification de verrouillage standard est une cible principale pour les attaques par injection de glitch : inverser artificiellement le drapeau de retenue contourne toute la branche de validation de sécurité. Dans les attaques physiques par décapage de la puce, la micro-sondage accède directement à ces emplacements de fusibles pour lire les bits d'état de verrouillage bruts, permettant des vidages complets de la mémoire programme sans modifier aucun code firmware.
3.2 Description de toutes les instructions 8051
Vous trouverez ci-dessous un glossaire de référence définissant chaque notation d'opérande standard utilisée dans le jeu d'instructions 8051 :
- A – Registre accumulateur ;
- Rn – Tout registre de travail (R0 à R7) dans la banque de registres RAM active ;
- Direct – Toute adresse RAM sur 8 bits, couvrant la RAM interne générale ou tous les registres de fonctions spéciales (ports E/S, registres de contrôle, périphériques d'état) ;
- @Ri – Octet RAM interne ou externe adressé indirectement, l'adresse étant contenue dans le registre pointeur R0 ou R1 ;
- #data – Constante immédiate 8 bits intégrée dans l'opcode (plage 0–255) ;
- #data16 – Constante immédiate 16 bits stockée dans les deuxième et troisième octets d'une instruction 3 octets (plage 0–65535) ;
- addr16 – Adresse programme complète sur 16 bits, capable de référencer n'importe quel emplacement dans l'espace d'adressage 64 Ko ;
- addr11 – Adresse partielle 11 bits, limitée aux cibles de saut/appel résidant dans la même page 2 Ko que l'octet suivant l'instruction ACALL/AJMP ;
- rel – Octet de décalage relatif pour les branchements courts, de -128 à +127 par rapport au premier octet de l'instruction suivant l'opcode de branchement. L'assembleur calcule automatiquement la valeur de décalage à ajouter ou soustraire du compteur de programme courant ;
- bit – Tout bit adressable de broche GPIO, drapeau de registre de contrôle ou bit d'état dans l'espace RAM/SFR ;
- C – Drapeau de retenue global contenu dans le registre d'état du programme PSW.
Ces notations d'opérandes définissent l'ensemble des modes d'adressage 8051 et sont essentielles pour localiser les adresses des fusibles de verrouillage dans la carte mémoire de la puce. Un flux de travail standard de rétro-ingénierie scanne le firmware binaire à la recherche de références d'opérandes directs pointant vers des adresses mémoire SFR de sécurité, puis trace tous les chemins d'instructions de lecture/écriture ciblant ces registres. Cette analyse statique révèle fréquemment des modes de test d'usine non documentés ou des chemins de code de porte dérobée cachés qui permettent une lecture complète de la mémoire même lorsque la protection par bit de verrouillage est active. Pour les projets légitimes de récupération de données firmware, une compréhension précise de chaque type d'opérande permet une reconstruction précise des dispositions complètes des vidages mémoire et une interprétation correcte des binaires de code extraits.
ACALL addr11 – Appel de sous-routine absolu dans une page de 2 Ko
addr11: Adresse mémoire de la sous-routine cible (décalage de page 11 bits)
Description : Cet opcode pousse sans condition l'adresse de retour du compteur de programme sur la pile système et saute vers l'adresse de sous-routine spécifiée. Une contrainte critique s'applique : l'octet suivant l'instruction courante et le point d'entrée de la sous-routine cible doivent résider dans la même limite de page de 2 Ko de la mémoire programme.
Syntaxe : ACALL [label_sous_routine];
Octets d'instruction : 2 (octet opcode, charge utile d'adresse 11 bits) ;
Drapeaux PSW affectés : Aucun drapeau d'état modifié par cette instruction.
EXEMPLE :
Valeur PC avant exécution = 0123h
Valeur PC après exécution = 0345h
Cet opcode d'appel de sous-routine apparaît fréquemment dans le firmware du bootloader MCU. Les attaquants capables d'écraser l'opérande addr11 via une corruption de mémoire par débordement de tampon peuvent rediriger l'exécution du programme vers des sous-routines de déverrouillage personnalisées qui désactivent les protections de verrouillage. Dans la plupart des scénarios de récupération par rétro-ingénierie, le patch binaire de l'adresse cible ACALL représente une méthode simple pour permettre l'extraction complète du firmware flash.
ADD A,Rn – Ajouter la valeur du registre de travail à l'accumulateur
A : Registre accumulateur
Rn : Tout registre de travail de R0 à R7
Description : L'opcode effectue une addition non signée sur un octet entre l'accumulateur et le registre de travail sélectionné Rn, stockant la somme résultante dans l'accumulateur.
Syntaxe : ADD A,Rn ;
Octets : 1 ;
Drapeaux PSW affectés : C, OV, AC
EXEMPLE :
Avant exécution : A = 12h, R5 = 23h
Après exécution : A = 35h, C = 0
ADD A,direct – Ajouter un octet d'adresse directe à l'accumulateur
Direct : Tout registre ou SFR avec adresse 0..255 (00h..FFh)
A : Accumulateur
Description : Cette instruction ajoute la valeur d'un octet direct à l'accumulateur, en tenant compte du drapeau de retenue. L'adressage direct permet d'accéder à n'importe quel SFR ou registre RAM général dans l'espace 0–7Fh (0–127). Le résultat est stocké dans l'accumulateur.
Syntaxe : ADD A, [adresse_directe];
Octets : 2 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant exécution : A=12h, TEMP=23h
Après exécution : A=35h, C=0
ADD A,@Ri – Ajouter un octet RAM interne adressé indirectement à l'accumulateur
Ri : Registre pointeur indirect R0 ou R1
A : Accumulateur
Description : Cette instruction ajoute à l'accumulateur la valeur d'un octet RAM dont l'adresse est contenue dans Ri (R0 ou R1).
Syntaxe : ADD A,@Ri ;
Octets : 1 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant exécution : A=12h, R0=30h, RAM[30h]=23h
Après exécution : A=35h, C=0
ADD A,#data – Ajouter une constante immédiate à l'accumulateur
A : Accumulateur
data : Constante 8 bits (00h..FFh)
Description : Ajoute une constante immédiate encodée dans l'instruction à l'accumulateur.
Syntaxe : ADD A,#data ;
Octets : 2 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant exécution : A=12h
Après exécution : A=35h, C=0
ADDC A,Rn – Ajouter le registre de travail et la retenue à l'accumulateur
Rn : Registre de travail
A : Accumulateur
Description : Cette instruction additionne l'accumulateur, le registre Rn et le drapeau de retenue C, et stocke le résultat dans l'accumulateur.
Syntaxe : ADDC A,Rn ;
Octets : 1 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant : A=12h, R3=23h, C=1 -> A=36h
ADDC A,direct – Ajouter un octet direct et la retenue à l'accumulateur
Direct : Adresse directe
A : Accumulateur
Description : Similaire à ADDC A,Rn mais avec un opérande direct.
Syntaxe : ADDC A,direct ;
Octets : 2 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant : A=12h, TEMP=23h, C=1 -> A=36h
ADDC A,@Ri – Ajouter un octet RAM indirect et la retenue à l'accumulateur
Ri : Pointeur indirect
A : Accumulateur
Description : Ajoute l'octet pointé par Ri et le drapeau C à l'accumulateur.
Syntaxe : ADDC A,@Ri ;
Octets : 1 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant : A=12h, R1=40h, RAM[40h]=23h, C=1 -> A=36h
ADDC A,#data – Ajouter une constante immédiate et la retenue à l'accumulateur
A : Accumulateur
data : Constante 8 bits
Description : Ajoute la constante et le drapeau C à l'accumulateur.
Syntaxe : ADDC A,#data ;
Octets : 2 ;
Drapeaux : C, OV, AC
EXEMPLE :
Avant : A=12h, C=1, #=23h -> A=36h
AJMP addr11 – Saut absolu dans la page 2 Ko
addr11: Adresse cible 11 bits
Description : Saut inconditionnel vers une adresse de la même page 2 Ko que l'octet suivant l'instruction AJMP. L'adresse est formée par la combinaison des 5 bits de poids fort du compteur de programme avec les 11 bits spécifiés.
Syntaxe : AJMP [label];
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
ANL A,Rn – ET logique bit à bit entre l'accumulateur et le registre de travail
Rn : Registre de travail
A : Accumulateur
Description : Effectue un ET bit à bit entre l'accumulateur et Rn, stocke le résultat dans A.
Syntaxe : ANL A,Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
Avant : A=C3h (11000011), R4=55h (01010101) -> A=41h (01000001)
ANL A,direct – ET bit à bit entre l'accumulateur et un octet direct
Direct : Adresse directe
A : Accumulateur
Description : ET logique entre A et l'octet direct, résultat dans A.
Syntaxe : ANL A,direct ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
Avant : A=C3h, TEMP=55h -> A=41h
ANL A,@Ri – ET bit à bit entre l'accumulateur et un octet RAM indirect
Ri : Pointeur indirect
A : Accumulateur
Description : ET logique entre A et l'octet pointé par Ri, résultat dans A.
Syntaxe : ANL A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
Avant : A=C3h, R0=30h, RAM[30h]=55h -> A=41h
ANL A,#data – ET bit à bit entre l'accumulateur et une constante immédiate
A : Accumulateur
data : Constante 8 bits
Description : ET logique entre A et la constante, résultat dans A.
Syntaxe : ANL A,#data ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
Avant : A=C3h, #=55h -> A=41h
ANL direct,A – ET bit à bit entre un octet direct et l'accumulateur, stocke dans l'octet direct
Direct : Adresse directe
A : Accumulateur
Description : Effectue un ET entre l'octet direct et A, puis stocke le résultat dans l'octet direct.
Syntaxe : ANL direct,A ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
Avant : TEMP=C3h, A=55h -> TEMP=41h
ANL direct,#data – ET bit à bit entre un octet direct et une constante, stocke dans l'octet direct
Direct : Adresse directe
data : Constante 8 bits
Description : ET entre l'octet direct et la constante, résultat dans l'octet direct.
Syntaxe : ANL direct,#data ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
Avant : TEMP=C3h, #=55h -> TEMP=41h
CJNE A,direct,rel – Comparer accumulateur et octet direct ; saut court si inégaux
A : Accumulateur
direct : Adresse directe
rel : Décalage relatif
Description : Compare l'accumulateur avec l'octet direct. Si différents, le programme saute à l'adresse PC + rel + 2 (car l'instruction fait 3 octets). Sinon, continue séquentiellement.
Syntaxe : CJNE A,direct,label ;
Octets : 3 ;
Drapeaux : C mis à 0 si A >= direct, sinon C=1
EXEMPLE :
Si A=12h et TEMP=23h -> saut vers label (car inégaux).
CJNE A,#data,rel – Comparer accumulateur et constante ; saut si inégaux
A : Accumulateur
data : Constante 8 bits
rel : Décalage
Description : Compare A et la constante ; saute si différents.
Syntaxe : CJNE A,#data,label ;
Octets : 3 ;
Drapeaux : C mis à 0 si A >= data, sinon C=1
EXEMPLE :
CJNE Rn,#data,rel – Comparer registre de travail et constante ; saut si inégaux
Rn : Registre de travail
data : Constante
rel : Décalage
Description : Compare Rn et la constante ; saute si différents.
Syntaxe : CJNE Rn,#data,label ;
Octets : 3 ;
Drapeaux : C=0 si Rn >= data, sinon C=1
EXEMPLE :
CJNE @Ri,#data,rel – Comparer octet RAM indirect et constante ; saut si inégaux
Ri : Pointeur indirect
data : Constante
rel : Décalage
Description : Compare l'octet pointé par Ri avec la constante ; saute si différents.
Syntaxe : CJNE @Ri,#data,label ;
Octets : 3 ;
Drapeaux : C=0 si RAM[Ri] >= data, sinon C=1
EXEMPLE :
CLR A – Mettre l'accumulateur à zéro
A : Accumulateur
Description : Met tous les bits de l'accumulateur à 0.
Syntaxe : CLR A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
CLR C – Mettre le drapeau de retenue à 0
C : Drapeau de retenue
Description : Efface le drapeau de retenue (C=0).
Syntaxe : CLR C ;
Octets : 1 ;
Drapeaux : C=0
EXEMPLE :
CLR bit – Mettre un bit adressable direct à 0
bit : Bit adressable
Description : Efface le bit spécifié.
Syntaxe : CLR [bit] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
CPL A – Complément (inversion) de l'accumulateur
A : Accumulateur
Description : Inverse tous les bits de l'accumulateur (0→1, 1→0).
Syntaxe : CPL A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
CPL C – Inverser le drapeau de retenue
C : Drapeau de retenue
Description : Inverse l'état du drapeau C (0↔1).
Syntaxe : CPL C ;
Octets : 1 ;
Drapeaux : C inversé
EXEMPLE :
CPL bit – Inverser un bit adressable direct
bit : Bit adressable
Description : Inverse l'état du bit spécifié.
Syntaxe : CPL [bit] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
DA A – Ajustement décimal de l'accumulateur (BCD)
A : Accumulateur
Description : Ajuste le contenu de l'accumulateur pour obtenir un résultat BCD (décimal codé binaire) après addition. Utilisé après une addition sur des nombres BCD.
Syntaxe : DA A ;
Octets : 1 ;
Drapeaux : C mis à jour si retenue BCD
EXEMPLE :
DEC A – Décrémenter l'accumulateur
A : Accumulateur
Description : Soustrait 1 à l'accumulateur.
Syntaxe : DEC A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
DEC Rn – Décrémenter le registre de travail
Rn : Registre de travail
Description : Soustrait 1 au registre Rn.
Syntaxe : DEC Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
DEC Rx – Décrémenter un octet direct
direct : Adresse directe
Description : Soustrait 1 à l'octet direct.
Syntaxe : DEC [adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
DEC @Ri – Décrémenter un octet RAM indirect
Ri : Pointeur indirect
Description : Soustrait 1 à l'octet pointé par Ri.
Syntaxe : DEC @Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
DIV AB – Division non signée de A par B
A : Accumulateur (dividende)
B : Registre B (diviseur)
Description : Divise A par B. Le quotient est stocké dans A, le reste dans B. Si B=0, les deux registres sont indéfinis et le drapeau OV est mis à 1.
Syntaxe : DIV AB ;
Octets : 1 ;
Drapeaux : OV=1 si division par zéro, C=0
EXEMPLE :
DJNZ Rn,rel – Décrémenter Rn et sauter si non nul
Rn : Registre de travail
rel : Décalage relatif
Description : Décrémente Rn. Si le résultat est non nul, saute à l'adresse PC+rel+2 ; sinon continue.
Syntaxe : DJNZ Rn,label ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
DJNZ Rx,rel – Décrémenter un octet direct et sauter si non nul
direct : Adresse directe
rel : Décalage
Description : Décrémente l'octet direct. Si non nul, saute.
Syntaxe : DJNZ [adresse],label ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
INC A – Incrémenter l'accumulateur
A : Accumulateur
Description : Ajoute 1 à l'accumulateur.
Syntaxe : INC A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
INC Rn – Incrémenter le registre de travail
Rn : Registre de travail
Description : Ajoute 1 au registre Rn.
Syntaxe : INC Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
INC Rx – Incrémenter un octet direct
direct : Adresse directe
Description : Ajoute 1 à l'octet direct.
Syntaxe : INC [adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
INC @Ri – Incrémenter un octet RAM indirect
Ri : Pointeur indirect
Description : Ajoute 1 à l'octet pointé par Ri.
Syntaxe : INC @Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
INC DPTR – Incrémenter le pointeur de données 16 bits
DPTR : Pointeur de données (DPH, DPL)
Description : Ajoute 1 au registre 16 bits DPTR.
Syntaxe : INC DPTR ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
JB bit,rel – Sauter si le bit est à 1
bit : Bit adressable
rel : Décalage relatif
Description : Si le bit spécifié est à 1, saute à l'adresse calculée ; sinon continue.
Syntaxe : JB bit,label ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
JBC bit,rel – Sauter si bit=1, puis effacer le bit
bit : Bit adressable
rel : Décalage
Description : Si le bit est à 1, on saute et on efface le bit (met à 0).
Syntaxe : JBC bit,label ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
JC rel – Sauter si drapeau de retenue C=1
rel : Décalage relatif
Description : Si C=1, saute à l'adresse PC+2+rel (car l'instruction fait 2 octets).
Syntaxe : JC label ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
JMP @A+DPTR – Saut indirect indexé
A : Accumulateur (décalage)
DPTR : Pointeur de données (base)
Description : Saute à l'adresse DPTR + A. Utile pour les tables de saut.
Syntaxe : JMP @A+DPTR ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
JNC rel – Sauter si drapeau de retenue C=0
rel : Décalage
Description : Si C=0, saute.
Syntaxe : JNC label ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
JNZ rel – Sauter si accumulateur non nul
rel : Décalage
Description : Si A ≠ 0, saute.
Syntaxe : JNZ label ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
JZ rel – Sauter si accumulateur nul
rel : Décalage
Description : Si A = 0, saute.
Syntaxe : JZ label ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
LCALL addr16 – Appel de sous-routine long (16 bits)
addr16: Adresse 16 bits complète
Description : Appelle une sous-routine située n'importe où dans l'espace 64 Ko. L'adresse de retour est empilée.
Syntaxe : LCALL [label] ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
LJMP addr16 – Saut long (16 bits)
addr16: Adresse 16 bits
Description : Saut inconditionnel vers n'importe quelle adresse 16 bits.
Syntaxe : LJMP [label] ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
MOV A,Rn – Copier Rn dans l'accumulateur
Rn : Registre de travail
A : Accumulateur
Description : Copie le contenu de Rn dans A.
Syntaxe : MOV A,Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOV A,direct – Copier l'octet direct dans l'accumulateur
direct : Adresse directe
A : Accumulateur
Description : Copie l'octet direct dans A.
Syntaxe : MOV A,[adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV A,@Ri – Copier l'octet RAM indirect dans l'accumulateur
Ri : Pointeur indirect
A : Accumulateur
Description : Copie l'octet pointé par Ri dans A.
Syntaxe : MOV A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOV A,#data – Charger une constante immédiate dans l'accumulateur
A : Accumulateur
data : Constante 8 bits
Description : Charge la constante dans A.
Syntaxe : MOV A,#data ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV Rn,A – Copier l'accumulateur dans Rn
Rn : Registre de travail
A : Accumulateur
Description : Copie A dans Rn.
Syntaxe : MOV Rn,A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOV Rn,direct – Copier l'octet direct dans Rn
Rn : Registre de travail
direct : Adresse directe
Description : Copie l'octet direct dans Rn.
Syntaxe : MOV Rn,[adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV Rn,#data – Charger une constante dans Rn
Rn : Registre de travail
data : Constante 8 bits
Description : Charge la constante dans Rn.
Syntaxe : MOV Rn,#data ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV direct,A – Copier l'accumulateur dans l'octet direct
direct : Adresse directe
A : Accumulateur
Description : Copie A dans l'octet direct.
Syntaxe : MOV [adresse], A ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV direct,Rn – Copier Rn dans l'octet direct
direct : Adresse directe
Rn : Registre de travail
Description : Copie Rn dans l'octet direct.
Syntaxe : MOV [adresse], Rn ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV direct,direct – Copier d'un octet direct vers un autre
direct1 : Destination
direct2 : Source
Description : Copie le contenu de direct2 vers direct1.
Syntaxe : MOV [dest], [source] ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
MOV direct,@Ri – Copier l'octet RAM indirect vers l'octet direct
direct : Destination directe
Ri : Pointeur indirect source
Description : Copie l'octet pointé par Ri dans l'octet direct.
Syntaxe : MOV [adresse], @Ri ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV direct,#data – Charger une constante dans l'octet direct
direct : Adresse directe
data : Constante 8 bits
Description : Charge la constante dans l'octet direct.
Syntaxe : MOV [adresse], #data ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
MOV @Ri,A – Copier l'accumulateur vers la RAM indirecte
Ri : Pointeur indirect
A : Accumulateur
Description : Copie A dans l'octet pointé par Ri.
Syntaxe : MOV @Ri, A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOV @Ri,direct – Copier l'octet direct vers la RAM indirecte
Ri : Pointeur indirect destination
direct : Source directe
Description : Copie l'octet direct vers l'emplacement pointé par Ri.
Syntaxe : MOV @Ri, [adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV @Ri,#data – Charger une constante dans la RAM indirecte
Ri : Pointeur indirect
data : Constante 8 bits
Description : Charge la constante dans l'octet pointé par Ri.
Syntaxe : MOV @Ri,#data ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV bit,C – Copier le drapeau de retenue dans un bit adressable
bit : Bit adressable
C : Drapeau de retenue
Description : Copie l'état de C dans le bit spécifié.
Syntaxe : MOV [bit], C ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
MOV C,bit – Copier un bit adressable dans le drapeau de retenue
C : Drapeau de retenue
bit : Bit adressable source
Description : Copie l'état du bit dans C.
Syntaxe : MOV C, [bit] ;
Octets : 2 ;
Drapeaux : C mis à jour
EXEMPLE :
MOVC A,@A+DPTR – Lire un octet de la mémoire programme à l'adresse A+DPTR
A : Accumulateur (décalage)
DPTR : Pointeur de données (base)
Description : Calcule l'adresse (A+DPTR) dans la mémoire programme, lit l'octet et le place dans A.
Syntaxe : MOVC A,@A+DPTR ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOVC A,@A+PC – Lire un octet de la mémoire programme à l'adresse A+PC
A : Accumulateur (décalage)
PC : Compteur de programme (base)
Description : Calcule l'adresse (A+PC) dans la mémoire programme, lit l'octet et le place dans A.
Syntaxe : MOVC A,@A+PC ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOVX A,@Ri – Lire un octet de la RAM externe (adresse 8 bits) dans l'accumulateur
Ri : Pointeur indirect (R0 ou R1)
A : Accumulateur
Description : Lit la RAM externe à l'adresse 8 bits contenue dans Ri, et place la valeur dans A.
Syntaxe : MOVX A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOVX A,@DPTR – Lire un octet de la RAM externe (adresse 16 bits) dans l'accumulateur
DPTR : Pointeur de données (adresse 16 bits)
A : Accumulateur
Description : Lit la RAM externe à l'adresse DPTR, et place la valeur dans A.
Syntaxe : MOVX A,@DPTR ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOVX @Ri,A – Écrire l'accumulateur dans la RAM externe (adresse 8 bits)
Ri : Pointeur indirect (adresse 8 bits)
A : Accumulateur
Description : Écrit le contenu de A dans la RAM externe à l'adresse pointée par Ri.
Syntaxe : MOVX @Ri,A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MOVX @DPTR,A – Écrire l'accumulateur dans la RAM externe (adresse 16 bits)
DPTR : Pointeur de données (adresse 16 bits)
A : Accumulateur
Description : Écrit A dans la RAM externe à l'adresse DPTR.
Syntaxe : MOVX @DPTR,A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
MUL AB – Multiplication non signée A × B
A : Accumulateur (multiplicande)
B : Registre B (multiplicateur)
Description : Multiplie A par B. Le produit 16 bits est stocké : octet de poids faible dans A, poids fort dans B. OV=1 si produit > 255.
Syntaxe : MUL AB ;
Octets : 1 ;
Drapeaux : OV=1 si >255, C=0
EXEMPLE :
NOP – Aucune opération
Description : Ne fait rien, consomme un cycle machine.
Syntaxe : NOP ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
ORL A,Rn – OU logique bit à bit entre A et Rn
Rn : Registre de travail
A : Accumulateur
Description : OU entre A et Rn, résultat dans A.
Syntaxe : ORL A,Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
ORL A,direct – OU logique entre A et un octet direct
direct : Adresse directe
A : Accumulateur
Description : OU entre A et l'octet direct, résultat dans A.
Syntaxe : ORL A,[adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
ORL A,@Ri – OU logique entre A et un octet RAM indirect
Ri : Pointeur indirect
A : Accumulateur
Description : OU entre A et l'octet pointé par Ri, résultat dans A.
Syntaxe : ORL A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
ORL A,#data – OU logique entre A et une constante
A : Accumulateur
data : Constante 8 bits
Description : OU entre A et la constante, résultat dans A.
Syntaxe : ORL A,#data ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
ORL direct,A – OU logique entre un octet direct et A, stocke dans l'octet direct
direct : Adresse directe
A : Accumulateur
Description : OU entre l'octet direct et A, résultat dans l'octet direct.
Syntaxe : ORL [adresse], A ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
ORL direct,#data – OU logique entre un octet direct et une constante, stocke dans l'octet direct
direct : Adresse directe
data : Constante 8 bits
Description : OU entre l'octet direct et la constante, résultat dans l'octet direct.
Syntaxe : ORL [adresse], #data ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
ORL C,bit – OU logique entre C et un bit adressable, résultat dans C
C : Drapeau de retenue
bit : Bit adressable
Description : C = C OR bit.
Syntaxe : ORL C,bit ;
Octets : 2 ;
Drapeaux : C mis à jour
EXEMPLE :
ORL C,/bit – OU logique entre C et l'inverse d'un bit, résultat dans C
C : Drapeau de retenue
/bit : Bit adressable inversé
Description : C = C OR (NOT bit).
Syntaxe : ORL C,/bit ;
Octets : 2 ;
Drapeaux : C mis à jour
EXEMPLE :
POP direct – Dépiler dans un octet direct
direct : Adresse directe destination
Description : Lit la valeur au sommet de la pile (pointée par SP) et la copie dans l'octet direct, puis décrémente SP.
Syntaxe : POP [adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
PUSH direct – Empiler un octet direct
direct : Adresse directe source
Description : Incrémente SP, puis copie l'octet direct à l'adresse pointée par SP.
Syntaxe : PUSH [adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
RET – Retour de sous-routine
Description : Dépile l'adresse de retour et saute à cette adresse.
Syntaxe : RET ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
RETI – Retour d'interruption
Description : Similaire à RET, mais réactive également le système d'interruptions.
Syntaxe : RETI ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
RL A – Rotation à gauche de l'accumulateur
A : Accumulateur
Description : Décale tous les bits de A d'une position vers la gauche, le bit7 passe en bit0.
Syntaxe : RL A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
RLC A – Rotation à gauche de l'accumulateur à travers la retenue
A : Accumulateur
Description : Rotation à gauche de 9 bits (A + C) : bit7 → C, C → bit0.
Syntaxe : RLC A ;
Octets : 1 ;
Drapeaux : C mis à jour
EXEMPLE :
RR A – Rotation à droite de l'accumulateur
A : Accumulateur
Description : Décale les bits vers la droite, le bit0 passe en bit7.
Syntaxe : RR A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
RRC A – Rotation à droite de l'accumulateur à travers la retenue
A : Accumulateur
Description : Rotation à droite de 9 bits (A + C) : bit0 → C, C → bit7.
Syntaxe : RRC A ;
Octets : 1 ;
Drapeaux : C mis à jour
EXEMPLE :
SETB C – Mettre le drapeau de retenue à 1
C : Drapeau de retenue
Description : C = 1.
Syntaxe : SETB C ;
Octets : 1 ;
Drapeaux : C=1
EXEMPLE :
SETB bit – Mettre un bit adressable à 1
bit : Bit adressable
Description : Met le bit spécifié à 1.
Syntaxe : SETB [bit] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
SJMP rel – Saut relatif court
rel : Décalage relatif (-128 à +127)
Description : Saut inconditionnel vers PC + 2 + rel (car l'instruction fait 2 octets).
Syntaxe : SJMP label ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
SUBB A,Rn – Soustraction de Rn et de la retenue de A
Rn : Registre de travail
A : Accumulateur
Description : A = A - Rn - C.
Syntaxe : SUBB A,Rn ;
Octets : 1 ;
Drapeaux : C, OV, AC
EXEMPLE :
SUBB A,direct – Soustraction de l'octet direct et de la retenue de A
direct : Adresse directe
A : Accumulateur
Description : A = A - direct - C.
Syntaxe : SUBB A,[adresse] ;
Octets : 2 ;
Drapeaux : C, OV, AC
EXEMPLE :
SUBB A,@Ri – Soustraction de l'octet RAM indirect et de la retenue de A
Ri : Pointeur indirect
A : Accumulateur
Description : A = A - (Ri) - C.
Syntaxe : SUBB A,@Ri ;
Octets : 1 ;
Drapeaux : C, OV, AC
EXEMPLE :
SUBB A,#data – Soustraction de la constante et de la retenue de A
A : Accumulateur
data : Constante 8 bits
Description : A = A - data - C.
Syntaxe : SUBB A,#data ;
Octets : 2 ;
Drapeaux : C, OV, AC
EXEMPLE :
SWAP A – Échanger les quartets de l'accumulateur
A : Accumulateur
Description : Échange le quartet haut (bits 4-7) avec le quartet bas (bits 0-3) de A.
Syntaxe : SWAP A ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
XCH A,Rn – Échange A et Rn
Rn : Registre de travail
A : Accumulateur
Description : Échange les contenus de A et Rn.
Syntaxe : XCH A,Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
XCH A,direct – Échange A et un octet direct
direct : Adresse directe
A : Accumulateur
Description : Échange A et l'octet direct.
Syntaxe : XCH A,[adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
XCH A,@Ri – Échange A et l'octet RAM indirect
Ri : Pointeur indirect
A : Accumulateur
Description : Échange A et l'octet pointé par Ri.
Syntaxe : XCH A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
XCHD A,@Ri – Échange les quartets bas de A et de l'octet RAM indirect
Ri : Pointeur indirect
A : Accumulateur
Description : Échange uniquement les 4 bits de poids faible de A et de l'octet pointé par Ri.
Syntaxe : XCHD A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
XRL A,Rn – OU exclusif bit à bit entre A et Rn
Rn : Registre de travail
A : Accumulateur
Description : A = A XOR Rn.
Syntaxe : XRL A,Rn ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
XRL A,direct – OU exclusif entre A et un octet direct
direct : Adresse directe
A : Accumulateur
Description : A = A XOR direct.
Syntaxe : XRL A,[adresse] ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
XRL A,@Ri – OU exclusif entre A et l'octet RAM indirect
Ri : Pointeur indirect
A : Accumulateur
Description : A = A XOR (Ri).
Syntaxe : XRL A,@Ri ;
Octets : 1 ;
Drapeaux : Aucun
EXEMPLE :
XRL A,#data – OU exclusif entre A et une constante
A : Accumulateur
data : Constante 8 bits
Description : A = A XOR data.
Syntaxe : XRL A,#data ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
XRL direct,A – OU exclusif entre un octet direct et A, stocke dans l'octet direct
direct : Adresse directe
A : Accumulateur
Description : direct = direct XOR A.
Syntaxe : XRL [adresse], A ;
Octets : 2 ;
Drapeaux : Aucun
EXEMPLE :
XRL direct,#data – OU exclusif entre un octet direct et une constante, stocke dans l'octet direct
direct : Adresse directe
data : Constante 8 bits
Description : direct = direct XOR data.
Syntaxe : XRL [adresse], #data ;
Octets : 3 ;
Drapeaux : Aucun
EXEMPLE :
Chapitre 4 : Microcontrôleur AT89S8253
Introduction
Plus de deux décennies se sont écoulées depuis la sortie du cœur 8051 original. Au cours de cette période, l'architecture a subi de nombreuses améliorations et extensions. Aujourd'hui, des dizaines de fabricants produisent des variantes compatibles sous des numéros de pièce différents. Les versions modernes offrent des fonctionnalités bien supérieures au modèle de base. La plupart de ces dérivés portent des étiquettes telles que "compatible 8051" ou "famille 8051". Ces étiquettes indiquent une architecture CPU identique et un modèle de programmation uniforme utilisant le jeu d'instructions standard. En pratique, la maîtrise d'un seul dispositif de cette famille permet de migrer vers n'importe quel autre modèle compatible, donnant accès à des centaines de références.
Ce chapitre se concentre sur le AT89S8253 du fabricant Atmel comme représentant de cette famille. Ce dispositif a été choisi pour son adoption industrielle massive, son faible coût unitaire et sa mémoire Flash programme. La caractéristique Flash le rend idéal pour le prototypage et les tests itératifs, car les images peuvent être effacées et reprogrammées des milliers de fois. De plus, son interface de programmation série SPI permet de reprogrammer le firmware même après soudure sur le circuit imprimé final.
Cependant, cette programmabilité en circuit pratique introduit des risques de sécurité critiques. Si les bits de verrouillage matériel ne sont pas programmés, le contenu complet de la mémoire Flash peut être lu via l'interface SPI. Atmel a intégré un mécanisme de verrouillage à trois niveaux pour bloquer l'extraction non autorisée. Néanmoins, les fusibles de sécurité ne sont pas invulnérables. Des rétro-ingénieurs malveillants ont réussi à décaper la puce et à micro-sonder pour contourner les protections et récupérer le firmware. Dans certains cas, la partition EEPROM qui stocke les paramètres sensibles peut être vidée via l'instruction MOVX si le bit EEMEN est activé. Cette vulnérabilité souligne la nécessité pour les développeurs de comprendre pleinement les mécanismes de sécurité natifs lors de la conception de produits nécessitant une confidentialité robuste.
Le AT89S8253 intègre également un temporisateur de surveillance (watchdog) qui peut être configuré pour détecter les tentatives d'altération et déclencher une réinitialisation système. Une configuration appropriée du watchdog constitue une contre-mesure anti-extraction : si un attaquant tente d'arrêter le CPU pour sonder la mémoire, le watchdog forcera une réinitialisation et interrompra les tentatives de récupération. Néanmoins, les attaquants peuvent exploiter des glitches d'horloge ou manipuler directement les registres de contrôle si ceux-ci ne sont pas protégés par le verrouillage. La combinaison des fusibles de verrouillage et du watchdog crée une barrière de sécurité multicouche qui augmente la complexité et le coût du clonage. Comme pour tous les MCU 8051, aucune primitive de sécurité unique n'offre une protection absolue. La récupération complète du firmware nécessite souvent de combiner plusieurs méthodologies d'attaque, y compris l'analyse par canaux auxiliaires, l'injection de fautes et le décapage complet du silicium.
4.1 Spécifications d'identification du AT89S8253
- Compatible à 100 % avec le jeu d'instructions 8051.
- 12 Ko de mémoire Flash programme programmable in-system via l'interface SPI.
- 2 Ko de mémoire EEPROM non volatile pour les données.
- Tension d'alimentation : 4V à 6V.
- Fréquence d'horloge : 0 à 24 MHz.
- 256 octets de RAM interne.
- 32 broches E/S réparties sur 4 ports.
- 3 temporisateurs/compteurs 16 bits.
- 9 sources d'interruptions.
- Modes basse consommation : Idle et Power-Down.
- UART asynchrone.
- Watchdog programmable.
- Protection par fusibles de verrouillage à 3 niveaux.
Le die est encapsulé dans trois formats standard : DIP, TQFP, PLCC. Le facteur de forme influence la difficulté des attaques par décapage. Les boîtiers plus grands (DIP, PLCC) sont plus faciles à disséquer que les TQFP compacts. Quelle que soit la variante, les fusibles de verrouillage restent la principale défense contre les lectures non autorisées via l'interface de programmation. Les bonnes pratiques exigent de programmer le niveau de verrouillage le plus élevé pour désactiver toutes les commandes de lecture SPI. De nombreuses équipes renforcent la sécurité en désactivant définitivement les broches de programmation SPI après la production.
4.2 Descriptions fonctionnelles des broches
VCC Alimentation positive (4V à 6V).
GND Masse.
Port 0 (P0.0–P0.7) En sortie, peut piloter 8 charges TTL. En entrée, haute impédance. En cas de mémoire externe, sert de bus d'adresse/données multiplexé.
Port 1 (P1.0–P1.7) Sortie 4 charges TTL, entrée avec résistance de rappel interne. Fonctions alternatives : T2, T2EX, SS, MOSI, MISO, SCK.
| Broche | Fonction alternative |
| P1.0 | T2 (entrée compteur externe Timer2) |
| P1.1 | T2EX (entrée de déclenchement Timer2) |
| P1.4 | SS (sélection esclave SPI) |
| P1.5 | MOSI |
| P1.6 | MISO |
| P1.7 | SCK |
Port 2 (P2.0–P2.7) Similaire au Port 1. En mémoire externe, fournit l'octet haut de l'adresse (A8–A15).
Port 3 (P3.0–P3.7) Fonctions alternatives : RXD, TXD, INT0, INT1, T0, T1, WR, RD.
| Broche | Fonction alternative |
| P3.0 | RXD (réception UART) |
| P3.1 | TXD (émission UART) |
| P3.2 | INT0 (interruption externe 0) |
| P3.3 | INT1 |
| P3.4 | T0 (entrée compteur Timer0) |
| P3.5 | T1 |
| P3.6 | WR (écriture mémoire externe) |
| P3.7 | RD (lecture mémoire externe) |
RST Réinitialisation matérielle (niveau haut).
ALE/PROG En fonctionnement normal, émet un signal d'horloge à Fosc/16. En programmation Flash, sert d'entrée de contrôle.
PSEN Signal de validation de la mémoire programme externe.
EA/VPP À la masse pour utiliser une mémoire programme externe ; à VCC pour utiliser la Flash interne. En programmation, reçoit +12V.
XTAL1 Entrée du circuit oscillateur.
XTAL2 Sortie de l'oscillateur.
4.3 Architecture mémoire du AT89S8253
Mémoire programme (Flash)
Les 12 Ko de Flash sont reprogrammables via l'interface SPI. La mémoire externe est optionnelle, mais la capacité interne suffit pour la plupart des applications. La Flash est la cible principale des attaques de récupération de firmware. Les fusibles de verrouillage bloquent les lectures externes, mais le décapage et la micro-sondage restent possibles. Atmel propose trois niveaux de verrouillage.
RAM (Random Access Memory)
La RAM interne est divisée en trois blocs :
- 128 octets de RAM générale,
- 128 octets réservés aux SFR,
- 128 octets supplémentaires de RAM auxiliaire accessibles uniquement par adressage indirect.
EEPROM
2 Ko de mémoire non volatile pour données. Stocke les numéros de série, clés cryptographiques, etc. Les protections de verrouillage limitent l'accès, mais le bit EEMEN peut permettre un vidage via MOVX si non protégé.
Extension mémoire externe
Compatible avec le 8051 standard : jusqu'à 64 Ko de programme et 64 Ko de données externes.
Modes d'adressage
Direct et indirect. L'adressage indirect est un vecteur d'attaque potentiel si les pointeurs sont corrompus.
4.4 Registres de fonctions spéciales (SFR)
Le AT89S8253 possède 40 SFR. Les 22 de base sont identiques aux 8051 classiques. Les SFR supplémentaires contrôlent les extensions. Parmi eux, EECON (contrôle EEPROM) est critique : si EEMEN est à 1, MOVX permet de lire toute l'EEPROM. WDTCON contrôle le watchdog.
Accumulateur (ACC)
Registre B
PSW (Program Status Word)
SP (Stack Pointer)
Ports P0, P1, P2, P3
Registres de travail R0–R7
AUXR (Auxiliaire)
- DISALE : 0 = ALE actif en continu ; 1 = ALE uniquement lors des accès MOVX/MOVC.
- Intel_Pwd_Exit : 0 = sortie de Power-Down sur front descendant ; 1 = front montant.
CLKREG (multiplicateur d'horloge)
- 0 : division par 2 de l'horloge externe.
- 1 : horloge externe directe (permet d'utiliser un cristal moitié moins rapide).
Pointeurs de données (DPTR)
DPTR est formé de DPH et DPL. Le bit DPS dans EECON sélectionne DPTR0 (DPS=0) ou DPTR1 (DPS=1).
Gestion de l'EEPROM
L'EEPROM de 2 Ko est accessible via MOVX lorsque EEMEN=1. Un tampon de 32 octets permet des écritures groupées via EELD.
Registre EECON
- WRTINH (lecture seule) : 1 si tension trop basse pour écriture EEPROM.
- RDY/BSY : 0 = cycle d'écriture en cours ; 1 = prêt.
- DPS : sélection du pointeur (0 = DPTR0, 1 = DPTR1).
- EEMEN : 0 = MOVX vers mémoire externe ; 1 = MOVX vers EEPROM interne.
- EEMWE : doit être à 1 pour autoriser les écritures EEPROM.
- EELD : 1 = active le tampon d'écriture groupée (32 octets).
4.5 Temporisateur de surveillance (WDT)
Le watchdog utilise l'horloge système. Il est désactivé par défaut. Une fois activé, il doit être rafraîchi périodiquement pour éviter une réinitialisation. Le registre WDTCON contrôle tout.
| Bits de prédiviseur | Temps |
| 0 | 0 | 0 | 16ms |
| 0 | 0 | 1 | 32ms |
| 0 | 1 | 0 | 64ms |
| 0 | 1 | 1 | 128ms |
| 1 | 0 | 0 | 256ms |
| 1 | 0 | 1 | 512ms |
| 1 | 1 | 0 | 1024ms |
| 1 | 1 | 1 | 2048ms |
WDTCON
- PS2-0 : prédiviseur (voir tableau).
- WDIDLE : 0 = watchdog actif en Idle ; 1 = suspendu.
- DISRTO : 0 = la réinitialisation du watchdog agit sur la broche RST ; 1 = pas d'effet sur RST.
- HWDT : 0 = mode logiciel (contrôlé par WDTEN) ; 1 = mode matériel (désactivation uniquement par reset).
- WSWRST : écriture 1 pour rafraîchir le watchdog en mode logiciel.
- WDTEN : 0 = désactivé ; 1 = activé (en mode logiciel).
Le watchdog est une contre-mesure contre les tentatives de vidage mémoire, car il réinitialise la puce si le CPU est bloqué.
4.6 Interruptions
Le AT89S8253 dispose de 6 sources d'interruptions (dont Timer2 et SPI). Elles sont gérées par les registres IE, IP et IPH. Les priorités vont de 0 à 3 (3 étant la plus haute).
IE (Interrupt Enable)
- EA : 0 = toutes les interruptions désactivées ; 1 = activation individuelle.
- ET2 : Timer2.
- ES : UART/SPI.
- ET1 : Timer1.
- EX1 : INT1.
- ET0 : Timer0.
- EX0 : INT0.
IP (Interrupt Priority)
IPH (Interrupt Priority High)
La priorité est donnée par la combinaison des bits IP et IPH.
| IP | IPH | Priorité |
| 0 | 0 | 0 (basse) |
| 0 | 1 | 1 |
| 1 | 0 | 2 |
| 1 | 1 | 3 (haute) |
Les vecteurs d'interruption sont : 0x03 (INT0), 0x0B (T0), 0x13 (INT1), 0x1B (T1), 0x23 (UART/SPI), 0x2B (T2).
4.7 Temporisateurs et compteurs
Trois temporisateurs : T0, T1 (identiques au 8051) et T2 (étendu). T2 est un temporisateur 16 bits avec modes capture, auto-reload, générateur de baud rate et générateur d'horloge.
T2CON (contrôle de T2)
- TF2 : drapeau de débordement (à effacer par logiciel).
- EXF2 : drapeau de capture/reload (sur front descendant T2EX).
- RCLK : 1 = T2 pour la réception UART ; 0 = T1.
- TCLK : 1 = T2 pour l'émission UART ; 0 = T1.
- EXEN2 : 1 = permet les événements sur T2EX.
- TR2 : 1 = démarre T2.
- C/T2 : 0 = horloge interne, 1 = compteur externe.
- CP/RL2 : 1 = mode capture, 0 = mode auto-reload.
Mode capture
Lorsque CP/RL2=1, un front sur T2EX copie TH2/TL2 dans RCAP2H/RCAP2L.
Mode auto-reload
CP/RL2=0. Au débordement, RCAP2H/RCAP2L est rechargé dans TH2/TL2. Le bit DCEN (dans T2MOD) permet un comptage bidirectionnel (T2EX=0 pour décrémenter, T2EX=1 pour incrémenter).
T2 comme générateur de baud rate
Si RCLK ou TCLK=1, T2 sert à générer le baud rate UART. La formule est donnée en figure.
T2 comme générateur d'horloge
En activant T2OE (dans T2MOD), la broche T2/P1.0 émet un signal carré de fréquence programmable.
4.8 UART
Le UART est compatible avec le 8051 standard. Il utilise les broches P3.0 (RXD) et P3.1 (TXD). Les modes sont configurés via SCON. La communication multiprocesseur est supportée via SADDR et SADEN.
4.9 Interface SPI
Le module SPI permet des communications synchrones full-duplex. Utilise les broches P1.5 (MOSI), P1.6 (MISO), P1.7 (SCK), P1.4 (SS). Les registres SPDR, SPSR, SPCR contrôlent le tout.
Le SPI sert également à la programmation in-system. Si les verrous sont désactivés, il permet de lire la Flash. Même avec verrouillage, des attaques par glitch sur SCK peuvent forcer la sortie des données.
4.10 Gestion de l'alimentation
Trois modes : Normal (~25mA), Idle (~6.5mA), Power-Down (~40µA). Contrôlés par le registre PCON.
- SMOD1 : double le baud rate UART.
- SMOD0 : sélectionne la fonction du bit 7 de SCON.
- POF : drapeau de mise sous tension.
- GF1, GF0 : bits usage général.
- PD : 1 pour entrer en Power-Down.
- IDL : 1 pour entrer en Idle.
Le mode Power-Down peut être utilisé comme contre-mesure anti-effraction. Le mode Idle est vulnérable aux glitches d'horloge.
Erreurs courantes de programmation
- La RAM est partagée entre registres, pile et variables. Il faut initialiser SP au-delà de 20h.
- Les SFR ne sont pas utilisables comme RAM générale.
- Les interruptions nécessitent la sauvegarde des registres (PUSH/POP).
- Les instructions indirectes (@Ri) ne peuvent pas accéder aux SFR.
- Les drapeaux TI et RI doivent être effacés manuellement.
Ces erreurs peuvent créer des vulnérabilités exploitables (débordement de pile, sauts intempestifs).
Liste des SFR adressables par bit
Les SFR dont l'adresse est multiple de 8 sont adressables par bit. Exemple : ACC à E0h.
| Registre | Adresse | Bits |
| ACC | E0h | E7..E0 |
- Liste des MCU SyncMOS 8051 rétro-ingéniérés par Mikatech :