Source NASM complète
; factorial.asm - Calcule n! (n ≤ 8 pour résultat 16-bit)
; Build: nasm -f bin factorial.asm -o factorial.com
; Run: DOSBox / FreeDOS / MASM
org 100h ; format .COM
section .data
prompt db 'Entrez n (0-8): $'
resultMsg db 13,10,'Factorielle = $'
newline db 13,10,'$'
num db 0
fact dw 1
section .text
start:
; --- Affiche prompt ---
mov ah, 09h
mov dx, prompt
int 21h
; --- Lit chiffre unique (0-9) ---
mov ah, 01h
int 21h
sub al, '0' ; ASCII vers binaire
mov [num], al
cmp al, 8
ja error ; n > 8 déborde 16-bit
; --- Boucle factorielle ---
mov cx, 1 ; accumulateur = 1
mov bl, [num] ; compteur = n
test bl, bl
jz print_result ; 0! = 1
fact_loop:
mov ax, cx
mul bx ; DX:AX = CX * BL
mov cx, ax ; résultat dans CX (suppose < 65536)
dec bl
jnz fact_loop
print_result:
mov ah, 09h
mov dx, resultMsg
int 21h
; --- Affiche CX en décimal (simplifié: suppose < 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 ; réutilise comme "Invalide"
int 21h
ret
; --- Sous-routine: affiche AX en décimal non-signé ---
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=reste
push dx ; sauve chiffre
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
Explication
- Entrée : Chiffre unique (0–8) via DOS INT 21h/01h.
- Boucle : Multiplication 16-bit (MUL BX) accumule dans CX.
- Sortie : Affichage décimal via DIV 10 répété.
- Limite : 8! = 40 320 tient en 16-bit ; 9! = 362 880 nécessite 32-bit.
Alternative moderne (Linux x86-64)
; factorial64.asm - NASM, appels système 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! (affichage omis pour brièveté)
mov rax, 60
xor rdi, rdi
syscall