[CODE] == > [COMPILATEUR] ==> CODE COMPILÉ MACHINE ============================================================== Assembleur Turbo Assembleur (Borland) prog{.com|.exe} Assembleur Microsoft Assembleur prog{.com|.exe} C++ Turbo C++ prog.exe, prog.obj, ... Instruction 80486 ================= But de l'assembleur remplacé des instructions machines par des instructions mnémoniques [ D6h ] [ 7Eh ] [ 02h ] 1101 0110 0111 1110 0000 0010 MOV AX 2
Les adresses mémoires (emplacement des octets dans les barrettes de mémoire)
sont définies par deux registres : Le segment (partie haute de l'adresse) et
l'offset (partie basse de l'offset).
On note l'adresse : "segment :[ offset ]"
(":" est le séparateur, les crochets "[" et "]" ne sont pas obligatoires)
Exemple: "DS:[DI]", "DS:[EDI].
BX peut servir d'offset mémoire pour le calcul.
CS: code segment (segment mémoire du code)
EIP/IP : Offset mémoire du code (inaccessible directement, modifiable indirectement avec l'instruction CALL, JMP, ou J[cas]).
DS: data segment (Segment mémoire des données)
ESI/SI : Offset mémoire utilisé avec DS.
ES: segment (segment mémoire)?
FS : (Autre segment mémoire)?
GS : (Autre segment mémoire)?
EDI/DI : Offset mémoire utilisé avec ES (ou FS ou GS si spécifié, exemple : "mov al, byte ptr gs:[10]").
SP: stack pointer (offset mémoire de la pile)
BP: ? pointer : habituellement une copie de SP, servant souvent à la lecture de la pile (en soustrayant une valeur)
SS: stack segment (segment mémoire de la pile)
Définition: Zone mémoire qui permet d'empiler de l'information.
Dernier entré, premier sortie.
Entrée: instruction PUSH
Sortie: instruction POP
Hauteur: valeur du registre [E]BP.
Segment mémoire : registre SS (Stack Segment)
Offset mémoire : registre ESP/SP. (on ne doit pas le modifier)
Accès en lecture seule d'un élément de la pile
Exemple: MOV AX,[BP-4]
On ne peut enlever un élément de la pile qui n'est pas sur le dessus car cela provoque un plantage du PC.
Le jeu d'instructions
Variable:
(Exemple: chaine db 'allo$', nombre dd (1), inconnu dw (?), float dw FEDCBA98h)Label:
[nom] + ":";Processeur - Jeu d'instruction:
Modèle mémoire:
.MODEL
.COM = tasm /t [nomprog] pas de CS, pas de DS = ASSUME CS:CODE, DS:CODE pas de ES, pas de SS = ASSUME ES:NOTHING, SS:NOTHING
.MODEL TINY .[processeur] ASSUME CS:CODE,DS:CODE ; Code dans même segment ASSUME ES:NOTHING,SS:NOTHING ; ES et SS ne sont pas utilisé CODE SEGMENT ; Segment de code ORG 100H ; Adresse de début du programme DEBUT: JMP START START: --> remplacé par .STARTUP PUSH CS ; Initialise POP DS ; le segment de données [instruction] MOV AX,4C00H ; Termine le programme INT 21H ; par une fonction de DOS CODE ENDS ; Fin du segment END DEBUT ; Référence le point d'entrée |
.MODEL TINY [non obligatoire] CODESEG ORG 100H .STARTUP ; Début des instructions ; DATASEG avant le END [instruction] RET ; Fin du programme ; (même que AX=4C00h, int 21h) DATASEG END |
ASSUME CS:CODE, DS:DATA ===> ASSUME ES:DATA __/ .MODEL SMALL .STACK 100H .DATA .CODE START: MOV AX,@DATA ; le même que .data MOV DS,AX MOV AX,4C00H INT 21H END START |
DOSSEG ; Macro pour le Modèle ; de segmentation de DOS ; non obligatoire .MODEL SMALL ; Petit modèle mémoire .STACK 100H ; 256 Octets pour la pile .DATA ; <Données> .CODE START: MOV AX,@DATA ; Initialise le MOV DS,AX ; segment de données ; <Instructions> MOV AX,4C00H INT 21H END START |
Constante: nomConstante EQU valeur Inclure d'autre code: ====================== include nomfichier.ext boucle ====== debut: CMP [reg], [donnees] ; comparaison JA fin ; saut selon la condition (JA = si plus grand saute) JMP debut ; sinon retourne au début... fin: ; label pour quitter LOOP label; ==> saute si [CX] > 0 (verif, saut apres décrémente cx) Macro: ====== <NomMacro> MACRO Var1[, Var2, ...] <instructions> ... ENDM Procédure: =========== <NomProcédure> PROC {NEAR|FAR} <instructions> ... RET <NomProcédure> ENDP Caractère à l'écran: MOV AX, 0B800h MOV ES, AX MOVE AL, <caractère> MOVE AH, <couleur> MOVE CX, <nbrepetion> REP STOSW ; incremente di (le curseur) <couleur> BLEU 01 ROUGE 04 BLANC 05 FLASH 128 couleur*16 = couleur de fond couleur = couleur du texte ensemble = couleur1*16 + couleur2
(nombre exprimé dans les registres en hexadécimal (nombreH)
Sorte de petit programme stocké en mémoire qui est appelé plus ou moins régulièrement et qui a une tâche spécifique. Il y en a 256 au maximum (2 exposant 8), et les premières sont intégrés dans le BIOS comme les interruptions de la carte vidéo ou le clavier. Certaines sont appelées à une fréquence constance : l'interruption 1Ch par exemple qui est un compteur qui incrémente (ajoute 1) une valeur 18.6 fois/seconde; d'autres sont appelées uniquement si on a besoin d'elle : l'interruption 09h du clavier est appelée à chaque pression ou relachement d'une touche.
10 (vidéo) PARAMETRE --AX-- ====== 00 03 ; mode texte 80x25 (efface l'écran) 00 13 ; mode texte 40x80 (32000 pixels) ======================================================================================================================================== 16 (clavier) PARAMETRE | RETOUR --AX-- |--AX-- AH AL AH AL =======+====== 00 tt ee ; attente et lecture d'une touche. ; ee = 0, si la touche (tt) est étendu ; sinon la touche est dans ee; 01 ; vérifie la présence d'une touche dans le tampon clavier aucune touche: ZF = 0 avec touche: ZF = 1 ======================================================================================================================================== ?? ???? PARAMÈTRE | RETOUR --AX-- --DX--|--AX-- --BX-- --DX-- AH AL DH DL |AH AL BH BL DH DL ==============+====================== 00 00 | ; fin d'impression ?????????? ======================================================================================================================================== 17 imprimante PARAMÈTRE | RETOUR --AX-- --DX--|--AX-- --BX-- --DX-- AH AL DH DL |AH AL BH BL DH DL ==============+====================== 00 cc nn nn |tt ; Imprime le charactere [cc] sur l'imprimante no [nnnn]. ; si (test (tt=40) == 0), l'imprimante n'est pas occupé!, elle a imprimé le charactère! ; si (test (tt=29) == 0), il n'y a pas d'erreur ======================================================================================================================================== 21 (dos) PARAMÈTRE | RETOUR --AX-- --DX--|--AX-- --BX-- --DX-- AH AL DH DL |AH AL BH BL DH DL ==============+====================== 02 cc | ; affiche le charactère [cc] à l'écran 08 | cc ; lit un charactère [cc] et le met dans [al] 09 OFFSET| ; affiche une chaine (adresse dans DS:DX) ; arrête au caractere '$' nn 0A OFFSET| ; lit une chaine d'au plus [nn] caractères (déclaration nomvar db 13 14 dup (32)) | ; retourne le nombre de car dans [nomvar] (deux premiers octets de la chaine (codé à l'envers)) | ; la chaine commence donc à l'adresse OFFSET NOMVAR+2 2A | js ; Date [js=jour de la semaine, 0=dimanche] 35 33 | vv vv ; vecteur d'interruption 33h (souris), retourne 0 si non initialisé 4C | ; retour au système d'exploitation ======================================================================================================================================== 33 (souris) PARAMÈTRE | RETOUR --AX-- --DX--|--AX-- --BX-- --DX-- AH AL DH DL |AH AL BH BL DH DL ==============+====================== 00 00 | rr ; initialise la souris; s'il y a une souris [rr]=-1 (11111110b) 00 01 | ; affiche le pointeur de la souris 00 02 | ; enleve le pointeur de la souris 00 03 | bb ; si [bb] != 0, un bouton a été cliqué 00 05 | aa ; si [aa] != 0, le bouton est enfoncé ======================================================================================================================================== tableau de chaine de caractère nomvar dw varchaine1 dw varchaine2 dw varchaine3 dw varchaine4 nomvar + 2 (longueur(dw) en octet) * position commence à 0. logique car l'adresse nomvar contient varchaine1 l'adresse nomvar + longueur du premier élément = varchaine2 l'adresse nomvar + longueur du premier élément + longueur varchaine2 = varchaine3 et puisque la longueur est toujours de 2 (data word (dw)) nomvar + (2 * 0) = varchaine1 nomvar + (2 * 1) = varchaine2 nomvar + (2 * 2) = varchaine3 nomvar + (2 * 3) = varchaine4 et en assembleur var * 3 == shl var, 1 DIV BX correspond à AX/BX => AX AX%BX => DX MUL nombre ax = nombre * ax
Description: Les flags, "indicateurs", sont des bits qui regroupés dans le registre de flag. Ces flags sont modifiés en fonction de l'exécution des différentes instructions. Ils sont utilisés en relation avec les opérateurs de comparaisons.
AF : Auxilliary Flag = indicateur de retenue auxiliaire. AF est l'auxiliary carry qui s'apparente au CF. CF : Carry Flag = Indicateur de retenue. Le Carry Flag est celui qui contient la retenue d'une opération, lorsque le résultat dépasse la capacité du registre. Le bit est alors placer dans le CF. DF : Dirrection Flag = Indicateur de direction de traitement des chaînes de caractères. Indique la manière de déplacer les pointeurs (MOVSB,STOSB) soit positivement, soit négativement. IF : Interrupt Flag = Indicateur d'exécution des interruptions dites "masquables". 0 : le processeur ne commande pas les interruptions 1 : le processeur commande les interruptions OF : Overflow Flag = Indicateur de débordement. Il permet de trouver et de corriger certaines erreurs produites par des instructions mathématiques. PF : Parity Flag = Indicateur de parité 0 : Impaire 1 : Paire (nombre de bits d'une opérande est pair) ZF : Zero Flag = Indique une valeur nulle. 0 : résultat est différent de 0 1 : résultat est égal à 0 Utile pour éviter les problèmes de divisions sur 0. SF : Sign Flag = Indicateur de signe 0 : Positif 1 : Négatif ??TF : Single Step Flag = Indicateur de débogage. CPAZSIDO 1 : CLD LODSB (AL = contenu de DS:SI SI++, DI++) STOSB (ES:DI = contenu de AL, SI++, DI++) MOVSB (ES:DI = contenu de DS:SI SI++, DI++) 0 : LODSB (AL = contenu de DS:SI SI--, DI--) STOSB (ES:DI = contenu de AL, SI--, DI--) MOVSB (ES:DI = contenu de DS:SI SI--, DI--)
Syntaxe: J[cas] {offset}
Description: Va à l'adresse {offset} si la condition [cas] est exacte. [cas] est une condition relative aux "flags" (drapeaux), elle doit être traduite par « Si le résultat d'une opération logique ... » (je prends comme exemple "CMP {a},{b}") :
(non signée) CZ 00 : JA est supérieur (a > b) 0 : JAE est supérieur ou égal (a => b) 0 : JNB est supérieur ou égal (a => b) 0 : JNC est supérieur ou égal (a => b) 1 : JB est inférieur (a < b) 1 : JC est inférieur (a < b) 11 : JBE est inférieur ou égal (a <= b) (signée) SZO 00 : JG est supérieur (a > b) = = : JGE est supérieur ou égal (a => b) ! = : JL est inférieur (a < b) !1= : JLE est inférieur ou égal (a <= b) (égalité) Z 1 : JE est égal (a = b) 1 : JZ est égal (a = b) 0 : JNE est différent (a >< b) 0 : JNZ est différent (a >< b)SAUTS CONDITIONNELS - CMP CPAZSIDO 1 : JB Jump Below < 1 : JNAE Jump Not Above or Eqal !> || != 1 : JC Jump Carry 0 : JAE Jump Above or Eqal > || = 0 : JNB Jump Not Below !< 0 : JNC Jump Not Carry 1 : JE Jump Equal == 1 : JZ Jump Zero = 0 0 : JNE Jump Not Equal != 0 : JNZ Jump Not Zero !0 1 : JO Jump Overflow 0 : JNO Jump Not Overflow 1 : JP Jump Parity 1 : JPE Jump Parity Even 0 : JNP Jump No Parity 0 : JPO Jump Parity Odd 1 : JS Jump Signed 0 : JNS Jump Not Signed 0 0 : JA Jump Above > 0 0 : JNBE Jump Not Below or Eqal !< || != 1 : JBE Jump Below or Equal < || = 1 : JNA Jump Not Above !> 1 : JBE Jump Below or Equal < || = 1 : JNA Jump Not Above !> 0= = : JG Jump Greater > 0= = : JNLE Jump Not Less or Equal !< || != = = : JGE Jump Greater or Equal > || = = = : JNL Jump Not Less !< 1 1 : JL Jump Less < 1 1 : JNGE Jump Not Greater or Equal !> || != 1 1 : JLE Jump Less or Equal < || = 1 1 : JNG Jump Not Greater !> 1 : JLE Jump Less or Equal < || = 1 : JNG Jump Not Greater !> CPAZSIDO
Accéder avec le registre DX et avec les instructions IN et OUT.
Syntaxe : AND {destination},{masque}
Description: Applique un "et" logique à {destination} par {masque}.
Tout bit de {destination} est mis à 0 si le bit correspondant de {masque} vaut 0, et est inchangé si le bit correspondant vaut 1 :
0 AND 0 -> 0
0 AND 1 -> 0
1 AND 0 -> 0
1 AND 1 -> 1
Syntaxe: CALL {adresse}
Description: Appelle une procédure qui est à l'adresse {adresse}. Si une ou plusieurs instructions PUSH précèdent un CALL, ce sont des paramètres qui sont stockés dans la pile. Dans ce cas la procédure commence par "PUSH [e]bp ; MOV [e]bp, [e]sp" et on peut trouver la lecture des paramètres avec des instructions du genre "MOV {registre},[ebp-{valeur}]". Il ne faudra surtout pas oublier le "RET [valeur]" à la fin de la procédure (voir plus bas).
Syntaxe: CMP {a}, {b}
Description: Compare les deux variables {a} et {b}.
Toujours suivit d'un saut conditionnel ("J[cas] {offset}", voir sa signification plus bas).
Syntaxe: CMPS[B/D/W]
Description: Compare l'octet/le mot/le double-mot DS:ESI à ES:EDI
Syntaxe: IN {destination},{port}
Description: Lit une valeur 8 bits sur le port {port} (16 bits) et la stocke dans {destination}. Le seul registre autorisé pour {port} est DX. Voir aussi OUT.
Syntaxe: IRET {valeur}
Description: Quitte l'interruption.
Est uniquement utilisé pour les programmes résident comme le
pilote de la souris par exemple.
Voir aussi RET.
Syntaxe: JMP {offset}
Description: Va inconditionnellement (sans condition) ("J" = Jump : Sauter) à l'adresse {offset}.
Syntaxe: LEA {destination},{source}
Description: Ecrit l'adresse de {source} dans {destination}. Equivaut à "MOV {destination}, OFFSET {source}".
Syntaxe: LDS {destination},{adresse}
Description: Copie l'adresse {adresse} en 32 bits dans le registre DS, son segment, et dans {destination} (16 bits), son offset.
Syntaxe: LES {destination},{adresse}
Description: Copie l'adresse {adresse} en 32 bits dans le registre ES, son segment, et dans {destination} (16 bits), son offset.
Syntaxe: LFS {destination},{adresse}
Description: Copie l'adresse {adresse} en 32 bits dans le registre FS, son segment, et dans {destination} (16 bits), son offset.
Syntaxe: LGS {destination},{adresse}
Description: Copie l'adresse {adresse} en 32 bits dans le registre GS, son segment, et dans {destination} (16 bits), son offset.
Syntaxe: LSS {destination},{adresse}
Description: Copie l'adresse {adresse} en 32 bits dans le registre SS, son segment, et dans {destination} (16 bits), son offset.
Syntaxe: LODS[B/D/W]
Description: Copie l'octet/le mot/le double-mot ES:EDI dans AL/AX/EAX (instruction inverse de STOS[B/W/D]).
Syntaxe: MOV {dst},{src}
Description: Copie la valeur {src} dans {dst}.
Syntaxe: MOVS[B/D/W]
Description: Copie l'octet/le mot/le double-mot DS:ESI dans ES:EDI.
Syntaxe: MOVZX {dst},{src}
Description: Etend à 32 bits le nombre contenu dans {src} (8 bits) et transfert le résultat dans {dst} (16 ou 32 bits).
Exemple: MOVZX ax,al : Efface la partie haute de AX (AH).
Syntaxe: MUL {source}
Description: Multiplie la destination explicite par {source}, les deux nombres sont considérés comme non signés. Utiliser "JC {adresse}" pour tester le débordement. La destination est fonction de la taille de source.
8 bits : la destination est AX (le multiplicateur est AL)
16 bits : la destination est DX:AX, c'est à dire AX contient la partie basse et DX la partie haute (le multiplicateur est AX)
32 bits : la destination est EDX:EAX, c'est à dire EAX contient la partie basse et EDX la partie haute (le multiplicateur est EAX)
Syntaxe: NOT {destination}
Description: Inverse les bits de {destination}
NOT 1 -> 0 NOT 0 -> 1
Syntaxe: OR {destination}, {masque}
Description: Applique un "OU logique" à {destination} par {masque}. Tout bit de {destination} est mis à 1 si le bit correspondant de {masque} vaut 1, et laissé inchangé si le bit correspondant vaut 0.
0 OR 0 -> 0 0 OR 1 -> 1 1 OR 0 -> 1 1 OR 1 -> 0
Syntaxe: OUT {source},{port}
Description: Ecrit la valeur {source} (8 bits) sur le port {port} (16 bits). Le seul registre autorisé pour {port} est DX.
Voir aussi IN.
Syntaxe: PUSH {valeur}
Description: Met une [valeur] dans la pile
Syntaxe: POP {registre}
Description: Sort une valeur de la pile et la stocke dans un [registre].
Syntaxe: REP {instruction}
Description: Répète l'instruction [instuction] ECX fois.
Syntaxe: RET {valeur}
Description: Quitte la procédure en cours. Si des paramètres ont été envoyés au CALL, [xxxx] est le nombre d'octets envoyés qui sont à sortir de la pile.
Voir aussi IRET.
Syntaxe: SHL {registre},{valeur}
Description: Décalage binaire du {registre} de {valeur} vers la gauche (L = Left),
les bits apparaissant à droite sont complétés par des zéros.
Exemple : "mov al, 3; shl al,2" donne al = 12, car 3 = 0011 et son décalage 1100.
En fait décaler de X revient à multiplier par 2^X (3*2^2 = 3*4 = 3*2*2 = 12).
Syntaxe: SHR {registre},{valeur}
Description: Décalage binaire du {registre} de {valeur} vers la droite (R = Right),
les bits apparaissant à gauche sont complétés par des zéros.
Exemple : "mov al, 12; shr al,2" donne al = 3, car 12 = 1100 et son décalage 0011.
En fait décaler de X revient à diviser par 2^X (12/(2^2) = 12/4 = 3).
Syntaxe: STOS[B/D/W]
Description: Copie AL/AX/EAX dans l'octet/le mot/le double-mot ES:EDI (inverse de LODS[B/W/D]).
Syntaxe: SCAS[B/D/W]
Description: Compare AL/AX/EAX à l'octet/le mot/le double-mot ES:EDI (permet de rechercher une valeur dans une chaine de caractères).
Syntaxe: TEST {source},{masque}
Description: Teste si les bits {masque} de {source} sont posés ou non, et modifie ZF en conséquence
(ZF posé si les bits de {source} sont posés, sinon ZF=0),
ce qui sera exploitable avec "JZ" ou "JNZ" par la suite. L'instruction permet de tester un bit particulier de {source}.
En particulier : TEST {a},{a} = Teste si la variable {a} est à zéro (pose ou non le drapeau ZF).
Syntaxe: XOR {destination},{masque}
Description: Applique un "ou exclusif" à {destination} par {masque}. Tout bit de {destination} est mis à 1 s'il diffère du bit correspondant de {masque}, et est mis à 0 s'il a la même valeur :
0 XOR 0 -> 0 0 XOR 1 -> 1 1 XOR 0 -> 1 1 XOR 1 -> 0
(c'est le même système que pour la multiplication de nombres relatifs : (+2)x(-3) = (-6), et (-3)x(-3)=9 par exemple)
XOR est utilisé en cryptographique car appliquer deux fois XOR à un même nombre avec le même "masque" redonne le nombre. Exemple :
24 xor 3 -> 27
27 xor 3 -> 24
XOR {a},{a} : Met à la variable {a} à zéro, beaucoup plus rapidement que "MOV {a},0" car XOR est une instruction de base du processeur.
ES:DI
Accessible seulement avec les registres..
0A000h:0000 : mémoire vidéo VGA : 256 couleurs : 320*200*64000 octets écriture: couleur sur un octet.