admin管理员组

文章数量:1390964

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

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

Share Improve this question asked Mar 16 at 23:00 big_dddddd_boybig_dddddd_boy 111 silver badge2 bronze badges 1
  • 2 Have you stepped through this with a debugger? That should quickly identify where the fault is. – Tangentially Perpendicular Commented Mar 16 at 23:02
Add a comment  | 

1 Answer 1

Reset to default 1

Please read Assembly registers in 64-bit architecture

  • e_primo is allowed to change the CL register that is part of the RCX register that controls your main loop.
  • start_fibo is allowed to change the CX register that is part of the RCX register that controls your main loop, as well as the DX register that is part of the RDX register that addresses the potencias array.

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   

本文标签: x86 64Segmentation fault in x8664 Assembly programStack Overflow