Reputation: 3
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
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...
Upvotes: 1