; ==========================================================
; 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

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: