Rétro-ingénierie de MCU

Déverrouillage de microcontrôleur - MikaTech

Nos valeurs et objectifs

À propos de MikaTech

Le temps a passé vite, depuis le jour où nous avons réalisé notre premier projet de rétro-ingénierie sur MCU 8051 en 1998, jusqu'à la mise en place de notre laboratoire de rétro-ingénierie d'un million de dollars en 2012, 14 années se sont écoulées. Aujourd'hui, nous lançons notre nouvelle activité de développement de systèmes visuels embarqués, avec l'espoir de servir encore 10 ans.

signature Peter Lee Co-fondateur et PDG

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 :

ACALL

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 :

ADD A,Rn

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 :

ADD A,Rx

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 :

ADD A,@Ri

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 :

ADD A,#X

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 :

ADDC A,Rn

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 :

ADDC A,Rx

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 :

ADDC A,@Ri

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 :

ADDC A,#X

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 :

AJMP

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 :

ANL A,Rn

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 :

ANL A,Rx

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 :

ANL A,@Ri

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 :

ANL A,#X

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 :

ANL Rx,A

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 :

ANL Rx,#X

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 :

CJNE A,Rx,rel

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 A,#X,rel

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 Rn,#X,rel

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 :

CJNE @Ri,#X,rel

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 A

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 C

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 :

CLR bit

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 A

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 C

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 :

CPL bit

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 :

DA A

DEC A – Décrémenter l'accumulateur

A : Accumulateur

Description : Soustrait 1 à l'accumulateur.

Syntaxe : DEC A ;
Octets : 1 ;
Drapeaux : Aucun

EXEMPLE :

DEC A

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 Rn

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 Rx

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 :

DEC @Ri

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 :

DIV AB

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 Rn,rel

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 :

DJNZ Rx,rel

INC A – Incrémenter l'accumulateur

A : Accumulateur

Description : Ajoute 1 à l'accumulateur.

Syntaxe : INC A ;
Octets : 1 ;
Drapeaux : Aucun

EXEMPLE :

INC A

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 Rn

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 Rx

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 @Ri

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 :

INC DPTR

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 :

JB bit,rel

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 :

JBC bit,rel

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 :

JC rel

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 :

JMP @A+DPTR

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 :

JNC rel

JNZ rel – Sauter si accumulateur non nul

rel : Décalage

Description : Si A ≠ 0, saute.

Syntaxe : JNZ label ;
Octets : 2 ;
Drapeaux : Aucun

EXEMPLE :

JNZ rel

JZ rel – Sauter si accumulateur nul

rel : Décalage

Description : Si A = 0, saute.

Syntaxe : JZ label ;
Octets : 2 ;
Drapeaux : Aucun

EXEMPLE :

JZ rel

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 :

LCALL

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 :

LJMP

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,Rn

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,Rx

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,@Ri

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 A,#X

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,A

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,Rx

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 Rn,#X

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 Rx,A

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 Rx,Rn

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 Rx,Ry

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 Rx,@Ri

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 Rx,#X

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,A

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,Rx

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 @Ri,#X

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 bit,C

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 :

MOV C,bit

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+DPTR

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 :

MOVC A,@A+PC

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,@Ri

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 A,@DPTR

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 @Ri,A

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 :

MOVX @DPTR,A

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 :

MUL AB

NOP – Aucune opération

Description : Ne fait rien, consomme un cycle machine.

Syntaxe : NOP ;
Octets : 1 ;
Drapeaux : Aucun

EXEMPLE :

NOP

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,Rn

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,Rx

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,@Ri

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 A,#X

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 Rx,A

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 Rx,#X

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

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 :

ORL C,/bit

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 :

POP direct

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 :

PUSH direct

RET – Retour de sous-routine

Description : Dépile l'adresse de retour et saute à cette adresse.

Syntaxe : RET ;
Octets : 1 ;
Drapeaux : Aucun

EXEMPLE :

RET

RETI – Retour d'interruption

Description : Similaire à RET, mais réactive également le système d'interruptions.

Syntaxe : RETI ;
Octets : 1 ;
Drapeaux : Aucun

EXEMPLE :

RETI

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 :

RL A

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 :

RLC A

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 :

RR A

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 :

RRC A

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 C

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 :

SETB bit

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 :

SJMP rel

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,Rn

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,Rx

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,@Ri

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 :

SUBB A,#X

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 :

SWAP A

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,Rn

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,Rx

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 :

XCH A,@Ri

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 :

XCHD A,@Ri

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,Rn

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,Rx

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,@Ri

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 A,#X

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 Rx,A

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 :

XRL Rx,#X

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.
Vue d'ensemble du AT89S8253

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.

BrocheFonction alternative
P1.0T2 (entrée compteur externe Timer2)
P1.1T2EX (entrée de déclenchement Timer2)
P1.4SS (sélection esclave SPI)
P1.5MOSI
P1.6MISO
P1.7SCK

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.

BrocheFonction alternative
P3.0RXD (réception UART)
P3.1TXD (émission UART)
P3.2INT0 (interruption externe 0)
P3.3INT1
P3.4T0 (entrée compteur Timer0)
P3.5T1
P3.6WR (écriture mémoire externe)
P3.7RD (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.
RAM

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.

SFR

Accumulateur (ACC)

ACC

Registre B

B

PSW (Program Status Word)

PSW

SP (Stack Pointer)

SP

Ports P0, P1, P2, P3

P0-P3

Registres de travail R0–R7

R0-R7

AUXR (Auxiliaire)

AUXR
  • 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)

CLKREG
  • 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).

DPTR0 DPTR1

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.

EEPROM

Registre EECON

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édiviseurTemps
00016ms
00132ms
01064ms
011128ms
100256ms
101512ms
1101024ms
1112048ms

WDTCON

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).

Interruptions

IE (Interrupt Enable)

IE
  • 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)

IP

IPH (Interrupt Priority High)

IPH

La priorité est donnée par la combinaison des bits IP et IPH.

IPIPHPriorité
000 (basse)
011
102
113 (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)

T2CON
  • 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.

Capture mode

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).

Auto-reload

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.

Baud rate

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.

Clock generator

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.

SCON

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.

SPI

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.

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.

RegistreAdresseBits
ACCE0hE7..E0
  • Liste des MCU SyncMOS 8051 rétro-ingéniérés par Mikatech :
  • Série F29Cxx : F29C31004T, F29C31004B, etc.

    Série S29Cxx : S29C31001B, S29C51001T, etc.

    Série MSUxx : MSU1958, MSU2952, etc.

    Série SM29xx : SM2951, SM2952, etc.

    Série SM59xx : SM59064, SM59128C, SM59128L, etc.

    Série SM79xx : SM7908, SM79108, etc.

    Série SM89xx : SM894051, SM8951, SM89516, etc.

Questions générales sur l'extraction de firmware


    temps de piratage

    Années

    28 +
    pays

    Pays

    110 +
    clients

    Clients

    5000 +
    projets

    Projets

    60000 +