Compter le nombre de caractères d'un fichier


Introduction

Comment compter le nombres de caractères d'un fichier et afficher le résultat.
Le problème ici, c'est le comptage dynamique... j'avoue ne pas encore savoir comment faire.
Alors je définis un tampon de 1024


Ecrire le programme count.asm

section .data
 filename db '/tmp/test', 0 ; Nom du fichier à lire
 buffer_size equ 1024 ; Taille du buffer pour lire le fichier
 read_msg db 'Nombre de caractères : ', 0
 read_msg_len equ $ - read_msg
 newline db 10, 0 ; Caractère de retour à la ligne

section .bss
 buffer resb buffer_size ; Buffer pour stocker les données lues
 count resq 1 ; Compteur de caractères (64 bits)
 num_str resb 21 ; Buffer pour le nombre converti en chaîne

section .text
 global _start

_start:
 ; Ouvrir le fichier en lecture seule
 mov rax, 5 ; sys_open
 lea rdi, [filename] ; Pointeur vers le nom du fichier
 mov rsi, 0 ; Flags (O_RDONLY)
 mov rdx, 0 ; Mode (non utilisé en lecture)
 syscall

 ; Vérifier si l'ouverture a réussi
 test rax, rax
 js exit ; Si rax est négatif, erreur lors de l'ouverture

 ; Stocker le descripteur de fichier
 mov rdi, rax ; Descripteur de fichier dans rdi pour les appels suivants

 ; Initialiser le compteur à zéro
 xor rax, rax
 mov [count], rax

read_loop:
 ; Lire du fichier dans le buffer
 mov rax, 3 ; sys_read
 lea rsi, [buffer] ; Pointeur vers le buffer
 mov rdx, buffer_size ; Nombre de bytes à lire
 syscall

 ; Vérifier si la fin du fichier a été atteinte
 test rax, rax
 jz display_result ; Si rax est zéro, fin du fichier

 ; Ajouter le nombre de bytes lus au compteur
 add [count], rax

 ; Continuer la lecture
 jmp read_loop

display_result:
 ; Convertir le compteur en chaîne
 mov rax, [count] ; Charger le compteur
 lea rdi, [num_str] ; Pointeur vers le buffer de la chaîne
 call int_to_string ; Convertir le nombre en chaîne

 ; Afficher le message
 mov rax, 4 ; sys_write
 mov rdi, 1 ; Descripteur de fichier stdout
 lea rsi, [read_msg] ; Message à afficher
 mov rdx, read_msg_len ; Longueur du message
 syscall

 ; Afficher le nombre de caractères
 mov rax, 4 ; sys_write
 mov rdi, 1 ; Descripteur de fichier stdout
 lea rsi, [num_str] ; Pointeur vers la chaîne du nombre
 mov rdx, 21 ; Longueur maximale de la chaîne du nombre
 syscall

 ; Afficher un retour à la ligne
 mov rax, 4 ; sys_write
 mov rdi, 1 ; Descripteur de fichier stdout
 lea rsi, [newline] ; Caractère de retour à la ligne
 mov rdx, 1 ; Longueur du caractère
 syscall

 ; Fermer le fichier
 mov rax, 6 ; sys_close
 syscall

exit:
 ; Terminer le programme
 mov rax, 1 ; sys_exit
 xor rdi, rdi ; Code de sortie
 syscall

; Fonction pour convertir un nombre entier en chaîne de caractères
int_to_string:
 mov rcx, 10 ; Base décimale
 mov rbx, rdi ; Sauvegarder le pointeur vers le buffer de la chaîne
 add rdi, 20 ; Pointer vers la fin du buffer
 mov byte [rdi], 0 ; Terminer la chaîne avec un null terminator

convert_loop:
 xor rdx, rdx ; Clear rdx avant la division
 div rcx ; Diviser rax par 10, résultat dans rax, reste dans rdx
 add dl, '0' ; Convertir le reste en caractère ASCII
 dec rdi ; Déplacer le pointeur de la chaîne vers la gauche
 mov [rdi], dl ; Stocker le caractère
 test rax, rax ; Vérifier si rax est zéro
 jnz convert_loop ; Continuer si non zéro

 mov rax, rbx ; Restaurer le pointeur vers le début du buffer
 ret

Assembler

nasm -f elf64 count.asm

Linker

ld count.o -o count

Lancer le programme

./user


↑ Haut de page