user2177693
user2177693

Reputation: 3

Segmentation Fault in Intel NASM

I'm trying to write a NASM assmembly program that will pass a 5x5 matrix to a subroutine, and this subroutine will return the largest value. What I do is push every element onto the stack, and then pop them off one by one when I'm comparing the values. I'm getting a "Segmentation Fault" error when I try to pop off these values, and I don't understand why


segment .data

        hello db "hello",0xa
        hellol equ $-hello

segment .bss

        largest resw 1
        temp resw 1

        matrix resw 25

segment .text

        global _start

_start:
        ;initializing matrix
        mov [matrix + 0*2],word 50 ;Row 1
        mov [matrix + 1*2],word 52
        mov [matrix + 2*2],word 28
        mov [matrix + 3*2],word 12
        mov [matrix + 4*2],word 9
        mov [matrix + 5*2],word 2 ;Row 2
        mov [matrix + 6*2],word 21
        mov [matrix + 7*2],word 3
        mov [matrix + 8*2],word 124
        mov [matrix + 9*2],word 1
        mov [matrix + 10*2],word 23 ;Row 3
        mov [matrix + 11*2],word 32
        mov [matrix + 12*2],word 55
        mov [matrix + 13*2],word 83
        mov [matrix + 14*2],word 325
        mov [matrix + 15*2],word 321 ;Row 4
        mov [matrix + 16*2],word 1
        mov [matrix + 17*2],word 22
        mov [matrix + 18*2],word 11
        mov [matrix + 19*2],word 2
        mov [matrix + 20*2],word 213 ;Row 5
        mov [matrix + 21*2],word 4
        mov [matrix + 22*2],word 52
        mov [matrix + 23*2],word 83
        mov [matrix + 24*2],word 32


        mov ecx,25 ;Set the loop counter to 25
        mov esi,0 ;set index counter to 0

        pushLoop: ;Push all the elements from matrix onto the stack
                mov eax,[matrix + esi*2]
                push eax
                inc esi
                        loop pushLoop

        call findLargest

        call printLargest ;Not yet implemented, only prints "hello"

exit:
        mov eax,1
        xor ebx,ebx
        int 0x80
;Exit


findLargest: ;Finds the largest number in matrix and stores it in "largest"

        mov ebx,0 ;ebx will store the largest value
        mov ecx,25
        largestLoop:
                pop eax         ;Error is here, Segmentation fault....
                cmp eax,ebx
                jle skip
                mov ebx,eax
                skip:
                        loop largestLoop
        ;End of largestLoop
        mov [largest],ebx

ret
;end of findLargest subroutine

printLargest:
        mov eax,4
        mov ebx,1
        mov ecx,hello
        mov edx,hellol
        int 0x80
ret

If I comment out the line that produces the error, the program will function properly

Thanks in advance for any help!

Upvotes: 0

Views: 477

Answers (1)

Gunner
Gunner

Reputation: 5884

Why are you pushing each element? Just pass the address of the matrix to your procedure.

Also, when you push those elements then call a function, those elements are on the stack NOT in eax, so they will be in esp. The stack is DWORD aligned, not word aligned.

If those are the values you are using, you could just set the values of the array in your data section.

Now that is out of the way, first thing you should do/try is looping through the array and print each element. Once you have that down, modify to test for the largest number.

segment .data
fmt         db "%d",10, 0
matrix      dd 50, 52, 28, 12, 9, 2, 21, 3, 124, 1, 23, 32, 55, 83
            dd 325, 321, 1, 22, 11, 2, 213, 4, 52, 83, 32
matrix_len equ ($ - matrix) / 4 - 1

segment .text

extern printf, exit
global _start

_start:

    push    matrix
    call    findLargest

    call    exit

findLargest:
    push    ebp
    mov     ebp, esp                        ; array pointer is now in [ebp + 8]

    mov     esi, dword[ebp + 8]             ; pointer to our array
    mov     ebx, matrix_len                 ; loop counter
    mov     edi, 0                          ; 

PrintEm:
    push    dword [esi + edi * 4]           ; print each element in the array = Base pointer + index * scale
    push    fmt
    call    printf
    add     esp, 4 * 2 
    inc     edi                             ; step index
    dec     ebx                             ; decrease loop counter
    jns     PrintEm                         ; if not -1 repeat loop

    mov     esp, ebp
    pop     ebp
    ret     4                               ; pushed 1 dword

Ok, that loops through the matrix array and properly prints each value. Now modify it to find the largest value...

enter image description here

Upvotes: 1

Related Questions