X86 Assembly Printing Max in Array возвращает ошибку сегментации (ядро сброшено) - PullRequest
0 голосов
/ 10 ноября 2018

Моя программа работает, но с моей функцией printMax что-то не так. Программа завершается с

Ошибка сегментации (ядро сброшено).

Я попытался создать стек для этой функции и просто выполнить pusha popa, и в обоих случаях я сбросил ядро ​​ошибки сегмента.

Я пытался вызвать функцию, но она запускается дважды.
Есть идеи, что я делаю не так?

SECTION .data   ;data section
  msg1   : db "Here are the array elements:", 10, 0
  msg1Len: equ $-msg1
  msg2   : db "Here is the max value in the array:", 10, 0
  msg2Len: equ $-msg2

  arr    : dd 2,4,6,8,10,20,40
  arrLen : equ ($-arr)/4    ;number of elements = array length / 4

SECTION .bss
  max resd 1 ;declare and reserve space for max

SECTION .text
  global main
  main:
        push ebp
        mov ebp, esp

        mov ecx, msg1   ;print msg1
        mov edx, msg1Len
        call PString

        ;save array base address in ebx and save sizein in ecx
        mov ebx, arr
        mov ecx, arrLen; store num elements in ecx
        ;loop to print array
PrintArray:
        mov eax, [ebx] ;move value [ebx] to eax
        call PrintDec
        call Println
        add ebx, 4
        loop PrintArray

printMax:
    section .text
    pusha
;reset array to find max
        mov ebx, arr
        mov ecx, arrLen

loopForMax:

    mov eax, [ebx]
    cmp eax, [ebx +4]
    jle sameMax
    mov [max], eax

sameMax:
    add ebx, 4 ;move to next element 
    loop loopForMax

    mov ecx, msg2
    mov edx, msg2Len
    call PString

    mov eax, [max]
    call PrintDec
    call Println

    popa    
    ret

        ;exit program and clean stack
        mov esp, ebp
        pop ebp
        ret

PString:; save register values of the called function
    pusha
    mov eax,4 ; use 'write' system call = 4
    mov ebx,1 ; file descriptor 1 = STDOUT
    int 80h ; call the kernel

    ; restore the old register values of the called function
    popa
    ret

Println:
    ;will call PString func
    ;will change content of ecx and edx
    ;need to save registers used by the main program
    section .data
    nl db 10
    section .text
    pusha

    mov ecx, nl
    mov edx, 1
    call PString

    ;return original register values
    popa
    ret

PrintDec:
;saves all registers so they return unmodified
;build the function to handle dword size

    section .bss
    decstr resb 10 ; 10 32-bit digits
    ct1 resd 1     ;keep track of dec-string size

    section .text
    pusha; save registers

    mov dword[ct1],0 ;initially assume 0
    mov edi, decstr ; edi points to dec-string
    add edi, 9     ; moved to the last element of string
    xor edx, edx   ; clear edx for 64-bit div
whileNotZero:
    mov ebx, 10    ; get ready to divide by 10
    div ebx        ; divide by 10
    add edx, '0'   ; convert to ascii
    mov byte[edi], dl ; put it in string
    dec edi        ; move to next char in str
    inc dword[ct1] ; inc char counter
    xor edx, edx   ; clear edx
    cmp eax, 0     ;is remainder 0?
    jne whileNotZero ;if no, keep on looping

    inc edi        ; conversion finished, bring edi
    mov ecx, edi   ; back to start of string. make ecx
    mov edx, [ct1] ; point to counterm edx gets # chars
    mov eax, 4     ; print to stdout
    mov ebx, 1
    int 0x80       ; call kernel

    popa ; restore registers
    ret
...