英特尔NASM中的分段错误

时间:2013-03-16 18:39:34

标签: segmentation-fault nasm intel fault

我正在尝试编写一个NASM assmembly程序,它将5x5矩阵传递给子程序,这个子程序将返回最大值。我所做的是将每个元素推入堆栈,然后在比较值时逐个将它们弹出。当我尝试弹出这些值时,我收到“Segmentation Fault”错误,我不明白为什么


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 个答案:

答案 0 :(得分: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