Addition/soustraction/multiplication/division (non interactives)

Introduction

Nous allons créer des mini-programmes permettant d'effectuer des opérations de calcul simples
(addition/soustraction/multiplication/division), sans la possibilité pour l'utilisateur d'entrer des nombres.
Le programme doit présenter le résultat de l'opération sur le terminal.
C'est relativement complexe dans le cas de la multiplication et de la division


Programme 1 : addition.asm

Le but est d'afficher le résultat de l'addition 4 + 5.

section .data
result_message db '4 + 5 = ', 0 ; Message à afficher avant le résultat
result db '0' ; Réserver 1 octet pour le résultat (puisque 4+5 = 9, un seul chiffre est nécessaire)
newline db 10, 0 ; Caractère de nouvelle ligne suivi d'un terminateur nul

section .text
global _start

_start:
; Calculer 4 + 5 et stocker le résultat dans la variable result
mov eax, 4
add eax, 5

; Convertir le résultat en un caractère ASCII
add al, '0'
mov [result], al ; Stocker le caractère dans le résultat

; Écrire le message '4 + 5 = ' sur STDOUT
mov eax, 4 ; Numéro d'appel système pour sys_write dans FreeBSD
mov edi, 1 ; STDOUT
mov rsi, result_message ; Pointeur vers le message à afficher
mov rdx, 9 ; Longueur du message à afficher (y compris le résultat et le signe égal)
syscall ; Effectuer l'appel système pour écrire

; Écrire le résultat et une nouvelle ligne sur STDOUT
mov eax, 4 ; Numéro d'appel système pour sys_write dans FreeBSD
mov edi, 1 ; STDOUT
mov rsi, result ; Pointeur vers le résultat à afficher
mov rdx, 2 ; Longueur du résultat et de la nouvelle ligne
syscall ; Effectuer l'appel système pour écrire

; Terminer le programme correctement
mov eax, 1 ; Numéro d'appel système pour sys_exit dans FreeBSD
xor edi, edi ; Code de sortie 0
syscall ; Effectuer l'appel système pour quitter

Assembler

nasm -f elf64 addition.asm -o addition.o

Linker

ld addition.o -o addition

Lancer le programme

./addition

Programme 2 : soustraction.asm

Le but est d'afficher le résultat de la soustraction de 10 - 6

section .data
result_message db '10 - 6 = ', 0 ; Message à afficher avant le résultat
result db '0' ; Réserver 1 octet pour le résultat (puisque 10-6 = 4, un seul chiffre est nécessaire)
newline db 10, 0 ; Caractère de nouvelle ligne suivi d'un terminateur nul

section .text
global _start

_start:
; Calculer 10 - 6 et stocker le résultat dans la variable result
mov eax, 10
sub eax, 6

; Convertir le résultat en un caractère ASCII
add al, '0'
mov [result], al ; Stocker le caractère dans le résultat

; Écrire le message '10 - 6 = ' sur STDOUT
mov eax, 4 ; Numéro d'appel système pour sys_write dans FreeBSD
mov edi, 1 ; STDOUT
mov rsi, result_message ; Pointeur vers le message à afficher
mov rdx, 10 ; Longueur du message à afficher (y compris le résultat et le signe égal)
syscall ; Effectuer l'appel système pour écrire

; Écrire le résultat et une nouvelle ligne sur STDOUT
mov eax, 4 ; Numéro d'appel système pour sys_write dans FreeBSD
mov edi, 1 ; STDOUT
mov rsi, result ; Pointeur vers le résultat à afficher
mov rdx, 2 ; Longueur du résultat et de la nouvelle ligne
syscall ; Effectuer l'appel système pour écrire

; Terminer le programme correctement
mov eax, 1 ; Numéro d'appel système pour sys_exit dans FreeBSD
xor edi, edi ; Code de sortie 0
syscall ; Effectuer l'appel système pour quitter

Assembler

nasm -f elf64 soustraction.asm -o soustraction.o

Linker

ld soustraction.o -o soustraction

Lancer le programme

./soustraction

Programme 3 : multiplication.asm

Le but est d'afficher le résultat de la multiplication de 3*4

Là, c'est beaucoup, beaucoup plus compliqué !!

section .data
message db 'Le résultat est : ', 0
messageLen equ $-message
newline db 10, 0 ; Caractère de saut de ligne

section .bss
resultSpace resb 12 ; Réserve 12 octets pour le résultat en ASCII

section .text
global _start

_start:
; Calcul de 3 * 4
mov eax, 3
mov ebx, 4
mul ebx ; Après cette opération, eax = 3 * 4 = 12

; Convertir le nombre en chaîne de caractères
mov rdi, resultSpace + 11 ; Pointeur vers la fin de resultSpace
mov byte [rdi], 0 ; Terminer la chaîne avec un caractère nul
mov rbx, 10 ; Diviseur pour la conversion en décimal
mov rcx, 0 ; Initialiser le compteur de chiffres

convert_loop:
mov rdx, 0
div rbx ; Divise eax par 10
add dl, '0' ; Convertit le reste en caractère ASCII
dec rdi ; Décrémente le pointeur pour écrire le caractère
mov [rdi], dl ; Écrit le caractère dans resultSpace
inc rcx ; Incrémente le compteur de chiffres
test eax, eax
jnz convert_loop ; Continuer tant que eax n'est pas nul

; Afficher le message
mov rax, 4 ; syscall pour sys_write
mov rdi, 1 ; File descriptor 1 pour stdout
mov rsi, message ; Pointeur vers le message à afficher
mov rdx, messageLen ; Longueur du message
syscall ; Appel système pour écrire le message

; Afficher le résultat
mov rax, 4 ; syscall pour sys_write
mov rdi, 1 ; File descriptor 1 pour stdout
mov rsi, resultSpace ; Pointeur vers le résultat
mov rdx, rcx ; Longueur du résultat (nombre de chiffres)
syscall ; Appel système pour écrire le résultat

; Afficher le saut de ligne
mov rax, 4 ; syscall pour sys_write
mov rdi, 1 ; File descriptor 1 pour stdout
mov rsi, newline ; Pointeur vers le saut de ligne
mov rdx, 1 ; Longueur du saut de ligne
syscall ; Appel système pour écrire le saut de ligne

; Terminer le programme
mov rax, 1 ; syscall pour sys_exit
xor rdi, rdi ; Status 0
syscall ; Appel système pour terminer le programme

Assembler

nasm -f elf64 multiplication.asm -o multiplication.o

Linker

ld multiplication.o -o multiplication

Lancer le programme

./multiplication

Programme 4 : division.asm

Le but est d'afficher le résultat de la division 12/3

section .data
message db 'Le résultat de la division est : ', 0
messageLen equ $-message
newline db 10, 0 ; Caractère de saut de ligne

section .bss
resultSpace resb 12 ; Réserve 12 octets pour le résultat en ASCII

section .text
global _start

_start:
; Calcul de 12 / 3
mov eax, 12
mov ebx, 3
div ebx ; Après cette opération, eax = 12 / 3 = 4

; Convertir le nombre en chaîne de caractères
mov rdi, resultSpace + 11 ; Pointeur vers la fin de resultSpace
mov byte [rdi], 0 ; Terminer la chaîne avec un caractère nul
mov rbx, 10 ; Diviseur pour la conversion en décimal
mov rcx, 0 ; Initialiser le compteur de chiffres

convert_loop:
mov rdx, 0
div rbx ; Divise eax par 10
add dl, '0' ; Convertit le reste en caractère ASCII
dec rdi ; Décrémente le pointeur pour écrire le caractère
mov [rdi], dl ; Écrit le caractère dans resultSpace
inc rcx ; Incrémente le compteur de chiffres
test eax, eax
jnz convert_loop ; Continuer tant que eax n'est pas nul

; Afficher le message
mov rax, 4 ; syscall pour sys_write
mov rdi, 1 ; File descriptor 1 pour stdout
mov rsi, message ; Pointeur vers le message à afficher
mov rdx, messageLen ; Longueur du message
syscall ; Appel système pour écrire le message

; Afficher le résultat
mov rax, 4 ; syscall pour sys_write
mov rdi, 1 ; File descriptor 1 pour stdout
mov rsi, resultSpace ; Pointeur vers le résultat
mov rdx, rcx ; Longueur du résultat (nombre de chiffres)
syscall ; Appel système pour écrire le résultat

; Afficher le saut de ligne
mov rax, 4 ; syscall pour sys_write
mov rdi, 1 ; File descriptor 1 pour stdout
mov rsi, newline ; Pointeur vers le saut de ligne
mov rdx, 1 ; Longueur du saut de ligne
syscall ; Appel système pour écrire le saut de ligne

; Terminer le programme
mov rax, 1 ; syscall pour sys_exit
xor rdi, rdi ; Status 0
syscall ; Appel système pour terminer le programme

Assembler

nasm -f elf64 division.asm -o division.o

Linker

ld division.o -o division

Lancer le programme

./division


↑ Haut de page