>> Tecnologia Eletrônica >  >> Telefones >> Viva-voz de Conferência

Programa em Assembly: Cálculo de Fatorial (NASM, 16-bit DOS)

Código fonte completo NASM

; factorial.asm - Calcula n! (n ≤ 8 para resultado 16-bit)
; Compilação: nasm -f bin factorial.asm -o factorial.com
; Execução: DOSBox / FreeDOS / MASM
org 100h          ; formato .COM
section .data
prompt      db 'Digite n (0-8): $'
resultMsg   db 13,10,'Fatorial = $'
newline     db 13,10,'$'
num         db 0
fact        dw 1

section .text
start:
; --- Imprime prompt ---
mov ah, 09h
mov dx, prompt
int 21h

; --- Lê um dígito (0-9) ---
mov ah, 01h
int 21h
sub al, '0'      ; ASCII para binário
mov [num], al
cmp al, 8
ja error         ; n > 8 estoura 16-bit

; --- Loop fatorial ---
mov cx, 1        ; acumulador = 1
mov bl, [num]    ; contador = n
test bl, bl
jz print_result  ; 0! = 1

fact_loop:
; Melhor: multiplicação 16-bit
mov ax, cx
mul bx           ; DX:AX = CX * BL
mov cx, ax       ; resultado em CX (assume < 65536)
dec bl
jnz fact_loop

print_result:
mov ah, 09h
mov dx, resultMsg
int 21h

; --- Imprime CX como decimal (simplificado: assume < 10000) ---
mov ax, cx
call print_ax_dec

mov ah, 09h
mov dx, newline
int 21h
ret

error:
mov ah, 09h
mov dx, newline
int 21h
mov dx, prompt   ; reutiliza como "Inválido"
int 21h
ret

; --- Sub-rotina: imprime AX como decimal sem sinal ---
print_ax_dec:
push ax
push bx
push cx
push dx
mov bx, 10
mov cx, 0

div_loop:
xor dx, dx
div bx           ; AX/=10, DX=resto
push dx          ; salva dígito
inc cx
test ax, ax
jnz div_loop

print_digits:
pop dx
add dl, '0'
mov ah, 02h
int 21h
loop print_digits

pop dx
pop cx
pop bx
pop ax
ret

Explicação

  • Entrada: Dígito único (0–8) via DOS INT 21h/01h.
  • Loop: Multiplicação 16-bit (MUL BX) acumula em CX.
  • Saída: Impressão decimal via DIV 10 repetido.
  • Limite: 8! = 40.320 cabe em 16-bit; 9! = 362.880 precisa 32-bit.

Alternativa moderna (Linux x86-64)

; factorial64.asm - NASM, syscalls Linux
global _start
section .data
n dq 8
section .text
_start:
mov rax, 1
mov rcx, [n]
test rcx, rcx
jz .done
.loop:
mul rcx
dec rcx
jnz .loop
.done:
; rax = n! (impressão omitida para brevidade)
mov rax, 60
xor rdi, rdi
syscall