2013-03-16 1 views
0

5x5 행렬을 서브 루틴으로 전달하는 NASM assmembly 프로그램을 작성하려고합니다.이 서브 루틴은 가장 큰 값을 반환합니다. 내가하는 일은 모든 요소를 ​​스택에 푸시 한 다음 값을 비교할 때 하나씩 차례로 팝하는 것입니다. 나는이 값을 팝업 할 때 나는 "분할 오류"오류 받고 있어요, 나는 오류를 생산하는 라인을 주석 경우Intel NASM에서 세그먼트 화 오류


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 

이 프로그램이 제대로

를 작동합니다 왜 이해가 안 돼요

미리 도움 주셔서 감사합니다!

답변

1

왜 각 요소를 밀고 있습니까? 매트릭스의 주소를 프로 시저에 전달하십시오.

또한 이러한 요소를 누른 다음 함수를 호출하면 해당 요소가 eax가 아닌 스택에 있으므로 esp이됩니다. 스택은 워드로 정렬되지 않고 DWORD로 정렬됩니다.

사용중인 값인 경우 데이터 섹션에 배열 값을 설정할 수 있습니다.

이제이 방법을 사용하지 마십시오. 첫 번째로해야 할 일은 배열을 반복하면서 각 요소를 인쇄하는 것입니다. 일단 당신이 그것을 가지고 있으면, 가장 큰 수를 시험하기 위해 수정하십시오.

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 

좋아, 그 매트릭스 배열을 통해 루프와 각 값을 제대로 인쇄합니다. 이제 스택에 모든 요소를 ​​밀어에 문제가

enter image description here

+0

거기에 ... 가장 큰 값을 찾아 수정? 아니면 배열의 주소를 전달하는 것이 더 좋은 형태일까요? – user2177693

+0

주소를 전달하는 것이 더 빠르며 메모리를 덜 사용하고 코드가 적습니다. – Michael