assemblyx86-64machine-code

Segmentation fault in x86-64 Assembly program


Im making a very simple and basic assembly program (create array with 0 to 15, find the prime numbers, square each number and do the fibonacci in each). But everytime i run it i get a a segmentation fault (SIGSEGV), exit code: -11. No AIs could find out why, not even claude i guess they aint that trainded on assembly yet. Im using NASM 2.15.05 (on Linux x86_64). Can u help me please i would really appreciate it!!

section .data
    array_int db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
section .bss ; alocar espaços vazios de memoria
    primos resb 16 
    potencias resw 16
    fib_results resw 16 ; serão usados registradores de 16 bits para fibonacci
section .text 
    global _start 

e_primo:
    cmp al, 2     
    jl nao_primo  ; menor que 2 não é primo
    je sim_primo ; 2 é primo

    test al, 1 ; AND entre bits menos significat. Pares sempre comecam com 0. Pares não são primos
    jz nao_primo

    mov cl, 3 ; após inicializar primeiro divisor, "JUMP" pra checa_div
checa_div:
    mov bl, al ; 

    mov al, cl ; porque o AL é um registrador q tem q ser usado em MUL
    mul al ; AL por ele mesmo
    cmp al, bl ; checa se ja passou da sqrt do num: todos necessarios ja foram checados
    jg sim_primo

    mov al, bl
    
    mov ah, 0 ; zera registrador q armazena resto
    div cl
    
    cmp ah, 0
    je nao_primo

    add cl, 2 ; queremos checar apenas impares
    mov al, bl ; valor em AL é alterado na divisao
    jmp checa_div

nao_primo:
    mov al, 0
    ret
sim_primo:
    mov al, 1
    ret

start_fibo:
    mov dx, 0
    cmp al, 0 
    je end_fibo
    mov dx, 1
    cmp al, 1
    je end_fibo ; fibo 0 e 1 é eles mesmos

    mov bx, 0
    mov dx, 1

    mov cx, ax ; cx é usado no loop (AX vezes)
    sub cx, 1 ; primeiro ja tratado
fib_loop:
    mov ax, dx ; salva f(n) em ax
    add dx, bx ; dx = f(n) + f(n - 1) = f(n + 1)
    mov bx, ax ; f(n)

    loop fib_loop
end_fibo:
    mov ax, dx
    ret
    
_start:
    lea rsi, [array_int]
    lea rdi, [primos]
    lea rdx, [potencias]
    lea r15, [fib_results]
    mov rcx, 16

loop_array:
    mov al, [rsi] 
    call e_primo
    mov[rdi], al

    movzx ax, byte [rsi] ; restaura AL (registrador de 16 agora)
    mul al ; potencia do valor em AL
    mov [rdx], ax

    movzx ax, byte [rsi] 
    call start_fibo
    mov [r15], ax
    
    inc rsi
    inc rdi
    add rdx, 2
    add r15, 2
    loop loop_array
    
    mov rax, 60
    xor rdi, rdi
    syscall

idk i tried a lot of things


Solution

  • Please read Assembly registers in 64-bit architecture

    With these disruptive clobbers, rather sooner than later will the program try to address memory outside of .data or .bss and hence your segmentation fault.

    A solution is to preserve some registers (on the stack) before calling e_primo and start_fibo from within your main loop.

    loop_array:
        push rcx
        mov  al, [rsi] 
        call e_primo
    
        ...
    
        push rdx
        call start_fibo
        pop  rdx
    
        ...
    
        pop  rcx
        loop loop_array