Assemblea - Numeri
I dati numerici sono generalmente rappresentati nel sistema binario. Le istruzioni aritmetiche operano su dati binari. Quando i numeri vengono visualizzati sullo schermo o inseriti dalla tastiera, sono in formato ASCII.
Finora, abbiamo convertito questi dati di input in formato ASCII in binario per calcoli aritmetici e abbiamo riconvertito il risultato in binario. Il codice seguente mostra questo:
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
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
The sum is:
7
Tali conversioni, tuttavia, hanno un sovraccarico e la programmazione in linguaggio assembly consente di elaborare i numeri in modo più efficiente, in forma binaria. I numeri decimali possono essere rappresentati in due forme:
- Modulo ASCII
- BCD o formato decimale con codice binario
Rappresentazione ASCII
Nella rappresentazione ASCII, i numeri decimali vengono memorizzati come stringhe di caratteri ASCII. Ad esempio, il valore decimale 1234 viene memorizzato come -
31 32 33 34H
Dove 31H è il valore ASCII per 1, 32H è il valore ASCII per 2 e così via. Sono disponibili quattro istruzioni per l'elaborazione dei numeri nella rappresentazione ASCII:
AAA - Regolazione ASCII dopo l'aggiunta
AAS - Regolazione ASCII dopo la sottrazione
AAM - Regolazione ASCII dopo la moltiplicazione
AAD - Regolazione ASCII prima della divisione
Queste istruzioni non accettano operandi e presuppongono che l'operando richiesto sia nel registro AL.
L'esempio seguente utilizza l'istruzione AAS per dimostrare il concetto:
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
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
The Result is:
6
Rappresentanza BCD
Esistono due tipi di rappresentazione BCD:
- Rappresentazione BCD non imballata
- Rappresentazione BCD imballata
Nella rappresentazione BCD decompressa, ogni byte memorizza l'equivalente binario di una cifra decimale. Ad esempio, il numero 1234 viene memorizzato come -
01 02 03 04H
Ci sono due istruzioni per elaborare questi numeri:
AAM - Regolazione ASCII dopo la moltiplicazione
AAD - Regolazione ASCII prima della divisione
Le quattro istruzioni di regolazione ASCII, AAA, AAS, AAM e AAD, possono essere utilizzate anche con la rappresentazione BCD decompressa. Nella rappresentazione BCD compressa, ogni cifra viene memorizzata utilizzando quattro bit. Due cifre decimali vengono compresse in un byte. Ad esempio, il numero 1234 viene memorizzato come -
12 34H
Ci sono due istruzioni per elaborare questi numeri:
DAA - Regolazione dei decimali dopo l'aggiunta
DAS - Regolazione decimale dopo la sottrazione
Non è disponibile alcun supporto per la moltiplicazione e la divisione nella rappresentazione BCD compressa.
Esempio
Il seguente programma somma due numeri decimali a 5 cifre e visualizza la somma. Utilizza i concetti di cui sopra -
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 ' '
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
The Sum is:
35801