; ==========================================================
; ESTATÍSTICA BÁSICA DE UM VETOR
; Assembly x86-64 - NASM
; SEM BIBLIOTECA C
;
; Funções:
; monta_vetor
; calcula_soma
; encontra_maior
; calcula_media
; imprime_numero
;
; ==========================================================
global _start
section .data
; Quantidade de elementos
quantidade dq 5
; Dados de entrada
dados_entrada dd 10, 20, 5, 30, 15
; Textos
msg_soma db "Soma = "
tam_soma equ $ - msg_soma
msg_maior db "Maior = "
tam_maior equ $ - msg_maior
msg_media db "Media = "
tam_media equ $ - msg_media
quebra db 10
section .bss
; Vetor
vetor resd 5
; Resultados
soma resd 1
maior resd 1
media resd 1
; Espaço para transformar número em texto
buffer resb 12
section .text
; ==========================================================
; SUB-ROTINA: monta_vetor
;
; RDI = endereço dos dados de entrada
; RSI = endereço do vetor
; RDX = quantidade
; R10 = índice
; R9 = valor temporário
; ==========================================================
monta_vetor:
push rdi
push rsi
push rdx
mov r10, 0
LOOP_MONTA:
cmp r10, rdx
jge FIM_MONTA
mov r9d, [rdi + r10*4]
mov [rsi + r10*4], r9d
inc r10
jmp LOOP_MONTA
FIM_MONTA:
pop rdx
pop rsi
pop rdi
ret
; ==========================================================
; SUB-ROTINA: calcula_soma
;
; RDI = endereço do vetor
; RSI = quantidade
; R10 = índice
; R9 = valor temporário
; R8 = soma acumulada
;
; Retorno:
; EAX = soma
; ==========================================================
calcula_soma:
push rdi
push rsi
push r10
mov r8d, 0
mov r10, 0
LOOP_SOMA:
cmp r10, rsi
jge FIM_SOMA
mov r9d, [rdi + r10*4]
add r8d, r9d
inc r10
jmp LOOP_SOMA
FIM_SOMA:
mov eax, r8d
pop r10
pop rsi
pop rdi
ret
; ==========================================================
; SUB-ROTINA: encontra_maior
;
; RDI = endereço do vetor
; RSI = quantidade
; R10 = índice
; R9 = valor temporário
; R8 = maior valor
;
; Retorno:
; EAX = maior valor
; ==========================================================
encontra_maior:
push rdi
push rsi
push r10
; Primeiro elemento é considerado o maior
mov r8d, [rdi]
; Começa pelo segundo elemento
mov r10, 1
LOOP_MAIOR:
cmp r10, rsi
jge FIM_MAIOR
; valor = vetor[índice]
mov r9d, [rdi + r10*4]
; Compara valor com maior
cmp r9d, r8d
; Se valor <= maior
jle PROXIMO_MAIOR
; maior = valor
mov r8d, r9d
PROXIMO_MAIOR:
inc r10
jmp LOOP_MAIOR
FIM_MAIOR:
mov eax, r8d
pop r10
pop rsi
pop rdi
ret
; ==========================================================
; SUB-ROTINA: calcula_media
;
; RDI = soma
; RSI = quantidade
; RDX = auxiliar
;
; Retorno:
; EAX = média
; ==========================================================
calcula_media:
mov eax, edi
cdq
idiv esi
ret
; ==========================================================
; SUB-ROTINA: imprime_numero
;
; Recebe:
; EAX = número inteiro
;
; Converte o número para caracteres e imprime usando
; a system call WRITE do Linux.
; ==========================================================
imprime_numero:
mov r8, buffer + 11
mov byte [r8], 10
mov r9, 10
; Verifica se é negativo
cmp eax, 0
jge CONVERTE_NUMERO
neg eax
mov byte [buffer], '-'
CONVERTE_NUMERO:
xor rdx, rdx
div r9
add dl, '0'
dec r8
mov [r8], dl
test eax, eax
jnz CONVERTE_NUMERO
; Calcula tamanho do número
mov rsi, r8
mov rdx, buffer + 12
sub rdx, rsi
; System call write
mov rax, 1
mov rdi, 1
syscall
ret
; ==========================================================
; PROGRAMA PRINCIPAL
; ==========================================================
_start:
; ==========================================================
; 1 - MONTAR VETOR
; ==========================================================
mov rdi, dados_entrada
mov rsi, vetor
mov rdx, [quantidade]
call monta_vetor
; ==========================================================
; 2 - CALCULAR SOMA
; ==========================================================
mov rdi, vetor
mov rsi, [quantidade]
call calcula_soma
mov [soma], eax
; ==========================================================
; 3 - ENCONTRAR MAIOR
; ==========================================================
mov rdi, vetor
mov rsi, [quantidade]
call encontra_maior
mov [maior], eax
; ==========================================================
; 4 - CALCULAR MÉDIA
; ==========================================================
mov edi, [soma]
mov esi, [quantidade]
call calcula_media
mov [media], eax
; ==========================================================
; 5 - EXIBIR SOMA
; ==========================================================
mov rax, 1
mov rdi, 1
mov rsi, msg_soma
mov rdx, tam_soma
syscall
mov eax, [soma]
call imprime_numero
; ==========================================================
; 6 - EXIBIR MAIOR
; ==========================================================
mov rax, 1
mov rdi, 1
mov rsi, msg_maior
mov rdx, tam_maior
syscall
mov eax, [maior]
call imprime_numero
; ==========================================================
; 7 - EXIBIR MÉDIA
; ==========================================================
mov rax, 1
mov rdi, 1
mov rsi, msg_media
mov rdx, tam_media
syscall
mov eax, [media]
call imprime_numero
; ==========================================================
; 8 - ENCERRAR PROGRAMA
; ==========================================================
mov rax, 60
mov rdi, 0
syscall
To embed this project on your website, copy the following code and paste it into your website's HTML: