Números de Ponto Flutuante em Assembly NASM
Além de números inteiros, o Assembly NASM também permite trabalhar com números de ponto flutuante (floating-point numbers). Esses números representam valores reais compostos por mantissa e expoente, conforme o padrão IEEE 754. Por exemplo:
1.12345 × 10²
Nesse formato:
- 1.12345 é a mantissa.
- 2 é o expoente (potência de 10).
Sintaxe de Números de Ponto Flutuante no NASM
Em NASM, um número de ponto flutuante deve começar com um dígito decimal, podendo conter uma parte fracionária após o ponto.
O sinal - indica valores negativos (o + é opcional).
Exemplos válidos:
1.234 -23.456 0.23 -1.0
Se a parte inteira for 0, ela pode ser omitida:
Também é possível usar notação exponencial:
3.75e2 1.1e-1 1.e+4 -123.456e+789 +25.0e0 1.e3
Declaração de Variáveis com Ponto Flutuante
section .data
n1 dw 0.0
n2 dw 2.7
n3 dq 3.14159
n4 dq 0
n5 dq 1.234567e+2 ; 123.4567As diretivas dw e dq reservam espaço para armazenar números de ponto flutuante de diferentes tamanhos (detalhados ao final deste artigo).
Exemplo Prático: Conversão de Ponto Flutuante para Inteiro
A seguir, um exemplo simples em Linux que carrega um número de ponto flutuante, converte para inteiro e armazena o resultado:
global _start
section .data
num dq 4.6
section .text
_start:
movq xmm0, [num] ; carrega o número em xmm0
cvtsd2si rdi, xmm0 ; converte para inteiro e coloca em rdi
mov rax, 60
syscallCompilação e Execução
programicio@pc:~$ nasm -f elf64 float.asm -o float.o programicio@pc:~$ ld float.o -o float programicio@pc:~$ ./float programicio@pc:~$ echo $? 5
O valor 4.6 foi convertido e arredondado para 5.
Exemplo no Windows
global _start
section .data
num dq 4.6
section .text
_start:
movq xmm0, [rel num]
cvtsd2si rax, xmm0
retRepresentação IEEE 754
Os processadores x86-64 seguem o padrão IEEE 754, que define a estrutura interna dos números de ponto flutuante. Cada número é formado por três partes:
- Bit de sinal: indica se o número é positivo ou negativo.
- Mantissa: representa a parte fracionária.
- Expoente: define a escala (potência de 2).
Precisão Decimal (Decimal Precision)
A precisão decimal indica quantos dígitos decimais podem ser representados.
Por exemplo, o número 123.45 tem precisão decimal igual a 5.
Tipos de Ponto Flutuante em x86-64
| Tipo | Bits Totais | Bit de Sinal | Mantissa | Expoente |
|---|---|---|---|---|
| Precisão simples | 32 | 1 | 23 | 8 |
| Precisão dupla | 64 | 1 | 52 | 11 |
| Precisão estendida | 80 | 1 | 64 | 15 |
Números de Precisão Simples (Single Precision)
Usam 32 bits:
- 1 bit de sinal
- 8 bits de expoente (formato excess-127)
- 23 bits de mantissa (com um bit implícito igual a 1)
A mantissa, portanto, representa valores entre 1.0 e 2.0, enquanto a exponenciação por 2ⁿ ajusta a escala. Com esse formato, é possível representar aproximadamente 10⁻³⁸ a 10³⁸ com cerca de 6 a 7 dígitos decimais de precisão.
Números de Precisão Dupla (Double Precision)
Usam 64 bits:
- 1 bit de sinal
- 11 bits de expoente (formato excess-1023)
- 52 bits de mantissa (com um bit implícito igual a 1)
Esse formato oferece cerca de 15 dígitos decimais de precisão e um intervalo aproximado de 10⁻³⁰⁸ a 10³⁰⁸.
Diretivas NASM para Definição de Números Flutuantes
| Diretiva | Tamanho | Descrição |
|---|---|---|
db | 1 byte | byte (8 bits) |
dw | 2 bytes | word (16 bits) |
dd | 4 bytes | double word (32 bits) |
dq | 8 bytes | quad word (64 bits) |
dt | 10 bytes | ten word (80 bits) |
do | 16 bytes | octa word (128 bits) |
dy | 32 bytes | yword (256 bits) |
dz | 64 bytes | zword (512 bits) |
As quatro primeiras (db, dw, dd, dq) também são usadas para variáveis inteiras.
Resumo
- Números de ponto flutuante representam valores reais segundo o padrão IEEE 754.
- São compostos por sinal, mantissa e expoente.
- O NASM aceita notação decimal e exponencial.
- Instruções SSE (XMM) permitem manipular e converter valores flutuantes.
- Tipos mais usados: 32 bits (float) e 64 bits (double).