Assemblage - Procédures

Les procédures ou sous-routines sont très importantes en langage assembleur, car les programmes en langage assembleur ont tendance à être de grande taille. Les procédures sont identifiées par un nom. Après ce nom, le corps de la procédure est décrit, ce qui effectue un travail bien défini. La fin de la procédure est indiquée par une déclaration de retour.

Syntaxe

Voici la syntaxe pour définir une procédure -

proc_name:
   procedure body
   ...
   ret

La procédure est appelée à partir d'une autre fonction à l'aide de l'instruction CALL. L'instruction CALL doit avoir le nom de la procédure appelée comme argument comme indiqué ci-dessous -

CALL proc_name

La procédure appelée renvoie le contrôle à la procédure appelante à l'aide de l'instruction RET.

Exemple

Écrivons une procédure très simple nommée sum qui ajoute les variables stockées dans le registre ECX et EDX et renvoie la somme dans le registre EAX -

section	.text
   global _start        ;must be declared for using gcc
	
_start:	                ;tell linker entry point
   mov	ecx,'4'
   sub     ecx, '0'
	
   mov 	edx, '5'
   sub     edx, '0'
	
   call    sum          ;call sum procedure
   mov 	[res], eax
   mov	ecx, msg	
   mov	edx, len
   mov	ebx,1	        ;file descriptor (stdout)
   mov	eax,4	        ;system call number (sys_write)
   int	0x80	        ;call kernel
	
   mov	ecx, res
   mov	edx, 1
   mov	ebx, 1	        ;file descriptor (stdout)
   mov	eax, 4	        ;system call number (sys_write)
   int	0x80	        ;call kernel
	
   mov	eax,1	        ;system call number (sys_exit)
   int	0x80	        ;call kernel
sum:
   mov     eax, ecx
   add     eax, edx
   add     eax, '0'
   ret
	
section .data
msg db "The sum is:", 0xA,0xD 
len equ $- msg   

segment .bss
res resb 1

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

The sum is:
9

Structure des données des piles

Une pile est une structure de données de type tableau dans la mémoire dans laquelle les données peuvent être stockées et supprimées d'un emplacement appelé le «sommet» de la pile. Les données qui doivent être stockées sont "poussées" dans la pile et les données à récupérer sont "extraites" de la pile. Stack est une structure de données LIFO, c'est-à-dire que les données stockées en premier sont récupérées en dernier.

Le langage d'assemblage fournit deux instructions pour les opérations de pile: PUSH et POP. Ces instructions ont des syntaxes comme -

PUSH    operand
POP     address/register

L'espace mémoire réservé dans le segment de pile est utilisé pour l'implémentation de la pile. Les registres SS et ESP (ou SP) sont utilisés pour implémenter la pile. Le haut de la pile, qui pointe vers le dernier élément de données inséré dans la pile, est indiqué par le registre SS: ESP, où le registre SS pointe vers le début du segment de pile et le SP (ou ESP) donne le décalage dans le segment de pile.

L'implémentation de la pile présente les caractéristiques suivantes -

  • Seulement words ou doublewords pourrait être enregistré dans la pile, pas un octet.

  • La pile se développe dans le sens inverse, c'est-à-dire vers l'adresse mémoire inférieure

  • Le haut de la pile pointe vers le dernier élément inséré dans la pile; il pointe vers l'octet inférieur du dernier mot inséré.

Comme nous l'avons vu sur le stockage des valeurs des registres dans la pile avant de les utiliser pour une certaine utilisation; cela peut être fait de la manière suivante -

; Save the AX and BX registers in the stack
PUSH    AX
PUSH    BX

; Use the registers for other purpose
MOV	AX, VALUE1
MOV 	BX, VALUE2
...
MOV 	VALUE1, AX
MOV	VALUE2, BX

; Restore the original values
POP	BX
POP	AX

Exemple

Le programme suivant affiche l'ensemble du jeu de caractères ASCII. Le programme principal appelle une procédure nommée display , qui affiche le jeu de caractères ASCII.

section	.text
   global _start        ;must be declared for using gcc
	
_start:	                ;tell linker entry point
   call    display
   mov	eax,1	        ;system call number (sys_exit)
   int	0x80	        ;call kernel
	
display:
   mov    ecx, 256
	
next:
   push    ecx
   mov     eax, 4
   mov     ebx, 1
   mov     ecx, achar
   mov     edx, 1
   int     80h
	
   pop     ecx	
   mov	dx, [achar]
   cmp	byte [achar], 0dh
   inc	byte [achar]
   loop    next
   ret
	
section .data
achar db '0'

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
...
...