Créer un menu avec plusieurs propositions et y répondre
Introduction
Le programme doit présenter un menu avec 2 options (afficher le mot 'pomme' ou afficher le mot 'fraise')
L'utilisateur doit répondre en entrant le numéro d'index de l'un des 2 choix.
En fonction du choix, le programme renvoie le choix fait.
Je rajoute un petit bonus : effacer le shell au début de l'exécution du programme
Plusieurs versions de ce programme sont proposées ici, de la plus basique à la plus complexe (avec boucle en cas d'erreur de l'utilisateur et rupture de boucle)
Version 1 - Menu basique
Ecrivez le programme menu.asm suivant
section .data
clear_screen db 0x1b, '[2J', 0x1b, '[H' ; Séquence d'échappement ANSI pour effacer l'écran
menu_prompt db '-------------------------', 10
db '| Menu |', 10
db '-------------------------', 10
db 10
db '| [1] - Afficher 'pomme'', 10
db '| [2] - Afficher 'fraise'', 10
db 10
db '-------------------------', 10
db '| Faîtes votre choix : ', 0
menu_prompt_len equ $-menu_prompt
apple_message db 10
db 'Vous avez opté pour une pomme', 10
db 10
apple_len equ $-apple_message
strawberry_message db 10
db 'Vous avez opté pour une fraise', 10
db 10
strawberry_len equ $-strawberry_message
section .bss
user_choice resb 2 ; Réserve 2 octets pour le choix de l'utilisateur (caractère + newline)
section .text
global _start
_start:
; Effacer l'écran
mov rax, 4
mov rdi, 1
mov rsi, clear_screen
mov rdx, 4
syscall
; Afficher le menu
mov rax, 4
mov rdi, 1
mov rsi, menu_prompt
mov rdx, menu_prompt_len
syscall
; Lire le choix de l'utilisateur
mov rax, 3
mov rdi, 0
mov rsi, user_choice
mov rdx, 2
syscall
; Vérifier le choix de l'utilisateur
mov al, byte [user_choice]
cmp al, '1'
je display_apple
cmp al, '2'
je display_strawberry
; Si le choix n'est ni '1' ni '2', terminer le programme
jmp exit
display_apple:
; Afficher 'pomme'
mov rax, 4
mov rdi, 1
mov rsi, apple_message
mov rdx, apple_len
syscall
jmp exit
display_strawberry:
; Afficher 'fraise'
mov rax, 4
mov rdi, 1
mov rsi, strawberry_message
mov rdx, strawberry_len
syscall
jmp exit
exit:
; Terminer le programme
mov rax, 1
xor rdi, rdi
syscall
Assembler
nasm -f elf64 menu.asm
Linker
ld menu.o -o menu
Lancer le programme
./menu
Version 2 - Avec gestion d'erreur simple
Maintenant, comment gérer le fait que l'utilisateur se trompe et entre autre chose que 1 ou 2 ?
Eh bien, pour tout autre choix, il faut que le programme lui réponde qu'il n'a pas compris.
D'abord la version simple : le programme quitte après avoir affiché qu'il n'a pas compris.
section .data
clear_screen db 0x1b, '[2J', 0x1b, '[H' ; Séquence d'échappement ANSI pour effacer l'écran
menu_prompt db '-------------------------', 10
db '| Menu |', 10
db '-------------------------', 10
db 10
db '| [1] - Afficher 'pomme'', 10
db '| [2] - Afficher 'fraise'', 10
db 10
db '-------------------------', 10
db '| Faîtes votre choix : ', 0
menu_prompt_len equ $-menu_prompt
apple_message db 10
db 'Vous avez opté pour une pomme', 10
db 10
apple_len equ $-apple_message
strawberry_message db 10
db 'Vous avez opté pour une fraise', 10
db 10
strawberry_len equ $-strawberry_message
invalid_choice_message db 10
db 'Je n'ai pas compris votre choix', 10
db 10
invalid_choice_len equ $-invalid_choice_message
section .bss
user_choice resb 2 ; Réserve 2 octets pour le choix de l'utilisateur (caractère + newline)
section .text
global _start
_start:
; Effacer l'écran
mov rax, 4
mov rdi, 1
mov rsi, clear_screen
mov rdx, 4
syscall
; Afficher le menu
mov rax, 4
mov rdi, 1
mov rsi, menu_prompt
mov rdx, menu_prompt_len
syscall
; Lire le choix de l'utilisateur
mov rax, 3
mov rdi, 0
mov rsi, user_choice
mov rdx, 2
syscall
; Vérifier le choix de l'utilisateur
mov al, byte [user_choice]
cmp al, '1'
je display_apple
cmp al, '2'
je display_strawberry
; Si le choix n'est ni '1' ni '2', afficher un message d'erreur
mov rax, 4
mov rdi, 1
mov rsi, invalid_choice_message
mov rdx, invalid_choice_len
syscall
jmp exit
display_apple:
; Afficher 'pomme'
mov rax, 4
mov rdi, 1
mov rsi, apple_message
mov rdx, apple_len
syscall
jmp exit
display_strawberry:
; Afficher 'fraise'
mov rax, 4
mov rdi, 1
mov rsi, strawberry_message
mov rdx, strawberry_len
syscall
jmp exit
exit:
; Terminer le programme
mov rax, 1
xor rdi, rdi
syscall
Version 3 - Avec boucle infinie
Maintenant, il faut pouvoir offrir une seconde (voir troisième) chance à l'utilisateur qui s'est trompé.
Nous allons donc introduire une boucle !
section .data
clear_screen db 0x1b, '[2J', 0x1b, '[H' ; Séquence d'échappement ANSI pour effacer l'écran
menu_prompt db '-------------------------', 10
db '| Menu |', 10
db '-------------------------', 10
db 10
db '| [1] - Afficher 'pomme'', 10
db '| [2] - Afficher 'fraise'', 10
db 10
db '-------------------------', 10
db '| Faîtes votre choix : ', 0
menu_prompt_len equ $-menu_prompt
apple_message db 10
db 'Vous avez opté pour une pomme', 10
db 10
apple_len equ $-apple_message
strawberry_message db 10
db 'Vous avez opté pour une fraise', 10
db 10
strawberry_len equ $-strawberry_message
invalid_choice_message db 10
db 'Je n'ai pas compris votre choix', 10
db 'Veuillez faire un autre essai : ', 0
invalid_choice_len equ $-invalid_choice_message
section .bss
user_choice resb 2 ; Réserve 2 octets pour le choix de l'utilisateur (caractère + newline)
section .text
global _start
_start:
; Effacer l'écran
mov rax, 4
mov rdi, 1
mov rsi, clear_screen
mov rdx, 4
syscall
; Afficher le menu
mov rax, 4
mov rdi, 1
mov rsi, menu_prompt
mov rdx, menu_prompt_len
syscall
loop :
; Lire le choix de l'utilisateur
mov rax, 3
mov rdi, 0
mov rsi, user_choice
mov rdx, 2
syscall
; Vérifier le choix de l'utilisateur
mov al, byte [user_choice]
cmp al, '1'
je display_apple
cmp al, '2'
je display_strawberry
; Si le choix n'est ni '1' ni '2', afficher un message d'erreur et reboucler
mov rax, 4
mov rdi, 1
mov rsi, invalid_choice_message
mov rdx, invalid_choice_len
syscall
jmp loop
display_apple:
; Afficher 'pomme'
mov rax, 4
mov rdi, 1
mov rsi, apple_message
mov rdx, apple_len
syscall
jmp exit
display_strawberry:
; Afficher 'fraise'
mov rax, 4
mov rdi, 1
mov rsi, strawberry_message
mov rdx, strawberry_len
syscall
jmp exit
exit:
; Terminer le programme
mov rax, 1
xor rdi, rdi
syscall
Version 4 - Avec limite de 3 tentatives
Enfin, la dernière version : si l'utilisateur se trompe 3 fois, le programme doit lui dire Ciao et quitter !
section .data
clear_screen db 0x1b, '[2J', 0x1b, '[H' ; Séquence d'échappement ANSI pour effacer l'écran
menu_prompt db '-------------------------', 10
db '| Menu |', 10
db '-------------------------', 10
db 10
db '| [1] - Afficher 'pomme'', 10
db '| [2] - Afficher 'fraise'', 10
db 10
db '-------------------------', 10
db '| Faîtes votre choix : ', 0
menu_prompt_len equ $-menu_prompt
apple_message db 10
db 'Vous avez opté pour une pomme', 10
db 10
apple_len equ $-apple_message
strawberry_message db 10
db 'Vous avez opté pour une fraise', 10
db 10
strawberry_len equ $-strawberry_message
invalid_choice_message db 10
db 'Je n'ai pas compris votre choix', 10
db 'Veuillez faire un autre essai : ', 0
invalid_choice_len equ $-invalid_choice_message
max_attempts_message db 10, 10
db 'Trop de tentatives invalides. Au revoir !', 10
db 10
max_attempts_len equ $-max_attempts_message
section .bss
user_choice resb 2 ; Réserve 2 octets pour le choix de l'utilisateur (caractère + newline)
attempt_count resb 1 ; Réserve 1 octet pour compter le nombre de tentatives invalides
section .text
global _start
_start:
mov byte [attempt_count], 0 ; Initialiser le compteur de tentatives invalides à 0
; Effacer l'écran
mov rax, 4
mov rdi, 1
mov rsi, clear_screen
mov rdx, 4
syscall
; Afficher le menu
mov rax, 4
mov rdi, 1
mov rsi, menu_prompt
mov rdx, menu_prompt_len
syscall
loop:
; Lire le choix de l'utilisateur
mov rax, 3
mov rdi, 0
mov rsi, user_choice
mov rdx, 2
syscall
; Vérifier le choix de l'utilisateur
mov al, byte [user_choice]
cmp al, '1'
je display_apple
cmp al, '2'
je display_strawberry
; Si le choix n'est ni '1' ni '2', afficher un message d'erreur et incrémenter le compteur de tentatives
mov rax, 4
mov rdi, 1
mov rsi, invalid_choice_message
mov rdx, invalid_choice_len
syscall
inc byte [attempt_count] ; Incrémenter le compteur de tentatives invalides
cmp byte [attempt_count], 3 ; Vérifier si le compteur a atteint 3
je max_attempts_reached ; Sauter à max_attempts_reached si c'est le cas
jmp loop ; Reboucler si le compteur n'a pas atteint 3
max_attempts_reached:
; Afficher le message de tentatives maximales atteintes
mov rax, 4
mov rdi, 1
mov rsi, max_attempts_message
mov rdx, max_attempts_len
syscall
jmp exit ; Quitter le programme
display_apple:
; Afficher 'pomme'
mov rax, 4
mov rdi, 1
mov rsi, apple_message
mov rdx, apple_len
syscall
jmp exit
display_strawberry:
; Afficher 'fraise'
mov rax, 4
mov rdi, 1
mov rsi, strawberry_message
mov rdx, strawberry_len
syscall
jmp exit
exit:
; Terminer le programme
mov rax, 1
xor rdi, rdi
syscall
↑ Haut de page