Assemblage - Numéros
Les données numériques sont généralement représentées en système binaire. Les instructions arithmétiques fonctionnent sur des données binaires. Lorsque les nombres sont affichés à l'écran ou saisis à partir du clavier, ils sont sous forme ASCII.
Jusqu'à présent, nous avons converti ces données d'entrée sous forme ASCII en binaire pour les calculs arithmétiques et reconverti le résultat en binaire. Le code suivant montre ceci -
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov eax,'3'
sub eax, '0'
mov ebx, '4'
sub ebx, '0'
add eax, ebx
add eax, '0'
mov [sum], 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,sum
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
section .data
msg db "The sum is:", 0xA,0xD
len equ $ - msg
segment .bss
sum resb 1
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
The sum is:
7
De telles conversions ont cependant une surcharge et la programmation en langage assembleur permet de traiter les nombres de manière plus efficace, sous forme binaire. Les nombres décimaux peuvent être représentés sous deux formes -
- Forme ASCII
- BCD ou forme décimale codée binaire
Représentation ASCII
Dans la représentation ASCII, les nombres décimaux sont stockés sous forme de chaîne de caractères ASCII. Par exemple, la valeur décimale 1234 est stockée sous la forme -
31 32 33 34H
Où, 31H est la valeur ASCII pour 1, 32H est la valeur ASCII pour 2, et ainsi de suite. Il existe quatre instructions pour traiter les nombres en représentation ASCII -
AAA - Ajustement ASCII après addition
AAS - Ajustement ASCII après soustraction
AAM - Ajustement ASCII après multiplication
AAD - Ajustement ASCII avant la division
Ces instructions ne prennent aucun opérande et supposent que l'opérande requis se trouve dans le registre AL.
L'exemple suivant utilise l'instruction AAS pour démontrer le concept -
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
sub ah, ah
mov al, '9'
sub al, '3'
aas
or al, 30h
mov [res], ax
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov edx,1 ;message length
mov ecx,res ;message to write
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
section .data
msg db 'The Result is:',0xa
len equ $ - msg
section .bss
res resb 1
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
The Result is:
6
Représentation BCD
Il existe deux types de représentation BCD -
- Représentation BCD déballée
- Représentation BCD emballée
Dans la représentation BCD décompressée, chaque octet stocke l'équivalent binaire d'un chiffre décimal. Par exemple, le nombre 1234 est stocké sous la forme -
01 02 03 04H
Il y a deux instructions pour traiter ces nombres -
AAM - Ajustement ASCII après multiplication
AAD - Ajustement ASCII avant la division
Les quatre instructions de réglage ASCII, AAA, AAS, AAM et AAD, peuvent également être utilisées avec une représentation BCD décompressée. Dans la représentation BCD compressée, chaque chiffre est stocké en utilisant quatre bits. Deux chiffres décimaux sont regroupés dans un octet. Par exemple, le nombre 1234 est stocké sous la forme -
12 34H
Il y a deux instructions pour traiter ces nombres -
DAA - Ajustement décimal après addition
DAS - Réglage décimal après soustraction
Il n'y a pas de support pour la multiplication et la division dans la représentation BCD compressée.
Exemple
Le programme suivant additionne deux nombres décimaux à 5 chiffres et affiche la somme. Il utilise les concepts ci-dessus -
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov esi, 4 ;pointing to the rightmost digit
mov ecx, 5 ;num of digits
clc
add_loop:
mov al, [num1 + esi]
adc al, [num2 + esi]
aaa
pushf
or al, 30h
popf
mov [sum + esi], al
dec esi
loop add_loop
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov edx,5 ;message length
mov ecx,sum ;message to write
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
section .data
msg db 'The Sum is:',0xa
len equ $ - msg
num1 db '12345'
num2 db '23456'
sum db ' '
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
The Sum is:
35801