Montagem - Números

Os dados numéricos são geralmente representados no sistema binário. As instruções aritméticas operam com dados binários. Quando os números são exibidos na tela ou inseridos no teclado, eles estão no formato ASCII.

Até agora, convertemos esses dados de entrada no formato ASCII para binário para cálculos aritméticos e convertemos o resultado de volta para binário. O código a seguir mostra isso -

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 o código acima é compilado e executado, ele produz o seguinte resultado -

The sum is:
7

Essas conversões, entretanto, têm uma sobrecarga, e a programação em assembly permite o processamento de números de maneira mais eficiente, na forma binária. Os números decimais podem ser representados em duas formas -

  • Formulário ASCII
  • BCD ou forma decimal codificada em binário

Representação ASCII

Na representação ASCII, os números decimais são armazenados como string de caracteres ASCII. Por exemplo, o valor decimal 1234 é armazenado como -

31	32	33	34H

Onde 31H é o valor ASCII para 1, 32H é o valor ASCII para 2 e assim por diante. Existem quatro instruções para processar números na representação ASCII -

  • AAA - Ajuste ASCII após a adição

  • AAS - Ajuste ASCII após a subtração

  • AAM - Ajuste ASCII após a multiplicação

  • AAD - Ajuste ASCII antes da divisão

Estas instruções não levam nenhum operando e assumem que o operando necessário está no registro AL.

O exemplo a seguir usa a instrução AAS para demonstrar o conceito -

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 o código acima é compilado e executado, ele produz o seguinte resultado -

The Result is:
6

Representação BCD

Existem dois tipos de representação BCD -

  • Representação BCD descompactada
  • Representação BCD embalada

Na representação BCD descompactada, cada byte armazena o equivalente binário de um dígito decimal. Por exemplo, o número 1234 é armazenado como -

01	02	03	04H

Existem duas instruções para processar esses números -

  • AAM - Ajuste ASCII após a multiplicação

  • AAD - Ajuste ASCII antes da divisão

As quatro instruções de ajuste ASCII, AAA, AAS, AAM e AAD, também podem ser usadas com representação BCD descompactada. Na representação BCD compactada, cada dígito é armazenado usando quatro bits. Dois dígitos decimais são compactados em um byte. Por exemplo, o número 1234 é armazenado como -

12	34H

Existem duas instruções para processar esses números -

  • DAA - Ajuste decimal após adição

  • DAS - Ajuste decimal após a subtração

Não há suporte para multiplicação e divisão na representação BCD compactada.

Exemplo

O programa a seguir adiciona dois números decimais de 5 dígitos e exibe a soma. Ele usa os conceitos acima -

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 o código acima é compilado e executado, ele produz o seguinte resultado -

The Sum is:
35801