Langage d'assemblage - Syntaxe de base

Ce chapitre présente la structure de base, les règles de syntaxe et les conventions d'écriture des programmes en assembleur NASM, vous aidant à comprendre le squelette du code assembleur.


Structure de base d'un programme en assembleur

Un programme en assembleur NASM complet se compose généralement des parties suivantes :

Exemple

; Chemin du fichier : structure.asm
; Exemple de structure de base d'un programme NASM

section .data                       ; Section de données : stocke les données initialisées
    ; Définir les variables et les constantes ici
    msg db 'Hello, EXAMPLE!', 0xA
    len equ $ - msg

section .bss                        ; section BSS : stocke les données non initialisées
    ; Réserver de l'espace mémoire ici
    buffer resb 64                  ; Réserver un tampon de 64 octets

section .text                       ; section code : stocke les instructions exécutables
    global _start

_start:
    ; Écrire la logique du programme ici
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, len
    int 0x80

    mov eax, 1
    mov ebx, 0
    int 0x80
SectionObjectifCaractéristiques
.dataStocke les variables globales initialisées et les constantesTaille et contenu déterminés au moment de la compilation, stockés dans le fichier exécutable
.bssStocke les variables globales non initialiséesL'espace est alloué uniquement à l'exécution, n'occupe pas la taille du fichier exécutable
.textStocke les instructions machine exécutablesEn lecture seule, contient tout le code logique du programme

Au moins.textDes sections sont requises pour former un programme en assembleur valide. S'il n'y a pas de données, on peut omettre la.dataet.bsssection.


Format d'instruction en assembleur

Le format général de chaque instruction en assembleur est :

[标签:]   指令助记符   [操作数1 [, 操作数2 [, 操作数3]]]   [; 注释]

Explication de chaque partie :

PartieObligatoire ?Description
ÉtiquetteOptionalUn nom symbolique représentant une adresse mémoire, se terminant par un deux-points
Mnémonique de l'instructionRequisComme mov, add, sub, etc., indique au processeur ce qu'il doit faire
OpérandeFacultatif (certaines instructions n'ont pas d'opérande)L'objet de données manipulé par l'instruction peut être un registre, une adresse mémoire ou une valeur immédiate
CommentaireOptionalCommence par un point-virgule et continue jusqu'à la fin de la ligne

Exemple

; Exemples de divers formats d'instruction

; Instruction seule, sans opérande
ret                     ; Retour d'un sous-programme

; Instruction + un seul opérande
push eax                ; Empiler la valeur de eax sur la pile
inc ecx                 ; Ajouter 1 à ecx

; Instruction + deux opérandes (le plus courant)
mov eax, 42             ; Copier 42 dans le registre eax
add ebx, ecx            ; ebx = ebx + ecx

; Avec une étiquette
loop_start:             ; Étiquette : marque le début de la boucle
    dec ecx             ; Soustraire 1 à ecx
    jnz loop_start      ; Si ecx n'est pas 0, sauter en arrière vers loop_start

Conventions de commentaires

NASM utilisele point-virgule (;)pour indiquer des commentaires ; le contenu à partir du point-virgule jusqu’à la fin de la ligne est ignoré par l’assembleur.

Exemple

; Commentaire sur toute la ligne : explique le but du bloc de code suivant
; Calculer la somme de deux nombres et afficher le résultat

mov eax, 10             ; Commentaire en ligne : mettre 10 dans eax
add eax, 20             ; Commentaire en ligne : ajouter 20 à eax, maintenant eax = 30

Les commentaires sont extrêmement importants dans le code assembleur. Sans commentaires, même l’auteur peut ne pas comprendre le code assembleur après quelques semaines. Prenez l’habitude d’écrire un commentaire pour chaque instruction.


Règles de nommage des identifiants

Les identifiants (étiquettes, noms de variables, noms de constantes, etc.) doivent respecter les règles suivantes :

RègleDescription
Caractères de compositionLettres, chiffres, trait de soulignement _, point ., point d’interrogation ?, @, $, #, etc.
Caractère initialDoit commencer par une lettre, un tiret bas, un point ou un point d'interrogation ; ne peut pas commencer par un chiffre.
Sensibilité à la casseSensible à la casse par défaut (modifiable via les options de compilation)
Mots réservésNe peut pas avoir le même nom que les mnémoniques d'instruction, les noms de registres ou les mots-clés NASM.

Exemple

; Identifiants valides
my_variable:            ; Commence par une lettre + un tiret bas
.loop_start:            ; Commence par un point (étiquette locale)
?error_handler:         ; Commence par un point d'interrogation
counter2:               ; Lettre + chiffre

; Identifiants non valides (pour référence uniquement, ne pas utiliser)
; 1st_value: ; Erreur : ne peut pas commencer par un chiffre
; mov: ; Erreur : mov est un mot réservé
; my-variable: ; Erreur : le trait d'union n'est pas un caractère autorisé

Pseudo-instructions (Directives)

DirectivesSont des commandes adressées à l'assembleur, et non des instructions destinées au CPU ; elles contrôlent le processus d'assemblage et définissent des structures de données.

DirectivesObjectifExemple
dbDéfinir un octet (1 octet)byte_val db 0x55
dwDéfinir un mot (2 octets)word_val dw 0x1234
ddDéfinir un double mot (4 octets)dword_val dd 0x12345678
equDéfinir une constanteMAX_SIZE equ 256
resbRéserver un espace d'octetbuffer resb 128
reswRéserver un espace de motwbuf resw 64
resdRéserver un espace de double motdbuf resd 32
%defineConstante définie par macro%define COUNT 10

Conventions de casse

NASM, par défaut, pour les étiquettes et les identifiants,est sensible à la casse.:

Exemple

; Exemple de sensibilité à la casse

section .data
    msg db 'EXAMPLE', 0       ; Définir la variable msg

section .text
    global _start

_start:
    mov eax, MSG             ; Erreur : MSG et msg sont différents (sauf si le mode insensible à la casse est activé)
    mov eax, msg             ; Correct : msg correspond exactement à la définition

    MOV EAX, 42              ; Syntaxiquement correct : les mnémoniques d'instruction sont insensibles à la casse
    mov eax, 42              ; Style recommandé : utiliser des minuscules pour une meilleure lisibilité

Les mnémoniques d'instruction et les noms de registres sont insensibles à la casse (MOV、Mov、movmême effet), mais le style recommandé est uniformément en minuscules.


Représentation numérique

NASM prend en charge la représentation numérique dans plusieurs bases :

Exemple

; Représentation des différentes bases en NASM

mov eax, 42             ; Décimal : écrire le nombre directement
mov eax, 0x2A           ; Hexadécimal : préfixe 0x (style recommandé)
mov eax, 2Ah            ; Hexadécimal : suffixe h
mov eax, 0o52           ; Octal : préfixe 0o
mov eax, 52o            ; Octal : suffixe o
mov eax, 101010b        ; Binaire : suffixe b
mov eax, 0b101010       ; Binaire : préfixe 0b

Recommandé :0xutilisez le préfixe pour l'hexadécimal (par exemple,0x2A), il est donc moins susceptible d'être confondu avec des étiquettes.


Un exemple complet de syntaxe

Le programme suivant utilise de manière exhaustive les éléments de syntaxe ci-dessus pour calculer la somme de 1 à 10 et l'afficher :

Exemple

; Chemin du fichier : sum.asm
; Calculer 1+2+...+10 et afficher le caractère résultant

section .data
    result db 0                 ; Stocker le résultat du calcul (1 octet)
    newline db 0xA              ; Caractère de saut de ligne

section .text
    global _start

_start:
    ; Initialiser les registres et les variables
    mov ecx, 10                 ; Compteur de boucle : décompte à partir de 10
    mov eax, 0                  ; eax stocke la somme accumulée, initialement 0

sum_loop:                       ; Étiquette de début de boucle
    add eax, ecx                ; eax = eax + ecx
    dec ecx                     ; ecx décrémenté de 1
    jnz sum_loop                ; Si ecx != 0, continuer la boucle

    ; À ce stade, eax = 55 (10+9+...+1)
    add eax, '0'                ; Convertir le nombre en caractère ASCII ('0'=48, 55+48=103='g', incorrect)
                                ; La démonstration réelle nécessite une conversion plus complexe, voir les chapitres suivants

    ; Ici, on affiche seulement le résultat (démonstration simplifiée)
    mov [result], al            ; Stocker le résultat accumulé dans result

    ; Quitter le programme
    mov eax, 1
    mov ebx, 0
    int 0x80

Remarque : dans l'exemple ci-dessus, ajouter directement '0' n'est correct que lorsque le nombre se trouve dans la plage 0-9. La conversion des nombres à deux chiffres ou plus sera expliquée en détail dans les chapitres suivants.

Autres extensions