Dylan
Dylan

Reputation: 159

NASM x86 Segfault

The following code is meant to find the sum of all numbers less than 1000 that are multiples of 3 or 5. (Project Euler first problem).

However, it is giving a segmentation fault when I execute it. I have a feeling it may have something to do with after returning from my check function, I pop ebx off the stack before adding 8 to esp to restore the stack frame. Is this true and if so what can I do to fix it?

section .data
section .text
msg: db "%d", 0

global main
extern printf

main:

mov ebx, 0
mov ecx, 0
;MAINLOOP
loopstart:
    inc ebx         
    cmp ebx, 999        ;check if we are done
    je done         ;if we are, exit
    push 3
    push ebx        ;otherwise, check if our number is a multiple of 3
    call check
    pop ebx
    add esp, 8          ;fix stack pointer
    cmp eax, 1      ;if it is a multiple, add it to our sum
    je true
    push 5
    push ebx
    call check      ;otherwise check if multiple of 5
    pop ebx
    add esp, 8
    cmp eax, 1
    je true         ;if it is, add it to our sum
    jmp loopstart

true:
    add ecx, ebx
    jmp loopstart

done:
    push ecx
    push msg
    call printf
    add esp, 8
    ret


check:
    push ebp
    mov ebp, esp

    mov eax, [ebp+8]    
    mov ebx, [ebp+12]
    mov edx, 0
    div ebx

    cmp edx, 0
    je multiple
    mov eax, 0

    pop ebp
    mov esp, ebp
    ret

    multiple:
        mov eax, 1

        pop ebp
        mov esp, ebp
        ret

Upvotes: 0

Views: 599

Answers (1)

Dylan
Dylan

Reputation: 159

I have fixed the problem The error was in my check function, I was using

pop ebp
mov esp, ebp

which should have been

mov esp, ebp
pop ebp

I believe there were also some other errors with restoring stack frame etc. Here is the complete working code:

section .data
section .text
msg: db "%d", 0
global main
extern printf

main:

mov ebx, 0
mov ecx, 0

loopstart:

inc ebx
cmp ebx, 1000
je done
push ecx
push ebx
push 3
call check
add esp, 4
pop ebx
pop ecx
cmp eax, 1
je true
push ecx
push ebx
push 5
call check
add esp, 4
pop ebx
pop ecx
cmp eax, 1
je true
jmp loopstart

true:
add ecx, ebx
jmp loopstart

done:
push ecx
push msg
call printf
add esp, 8
ret

check:

    push ebp
    mov ebp, esp

    mov eax, [ebp+12]   
    mov ebx, [ebp+8]
    mov edx, 0
    div ebx

    cmp edx, 0
    je multiple
    mov eax, 0

    mov esp, ebp
    pop ebp
    ret

    multiple:
        mov eax, 1
        mov esp, ebp
        pop ebp
        ret

Upvotes: 1

Related Questions