Ошибка сегментации с использованием указателя стека и фрейма

#assembly #x86 #nasm

#сборка #x86 #nasm

Вопрос:

Я пытаюсь реализовать программу, которая сравнивает пару чисел из двух разных списков и сохраняет наибольшее число. Для доступа к параметрам должен использоваться регистр EBP.

         segment .bss
                ans     resb 4
                buff    resb 4
                largest resb 4
                test2   resb 1
        segment .data
                num1    db 1,2,3,4
                num2    db 5,1,7,2
msg1:      db "  "
msg_size1:             equ $-msg1

space1:  db " "
space1_size:         equ $-space1

        segment .text

        global _start

_start:
                    mov byte[test2], 0
                    mov word[largest], 0
                    mov word[ans], 0
                    mov word[buff], 0
                    mov esi, 0
                    mov bx, 0

label1:
                    cmp esi, 3
                    jg label3
                    mov ecx, [num1 esi]
                    mov edx, [num2 esi]

                    push ecx
                    push edx

                    ;;mov dword[test2], esi
                    call which_is_larger_procedure
                    add esp, 8
                    mov eax, [num2 esi]
                    mov [ans], eax

                    ;;mov esi, dword[test2]
        ;; mov [buff], esi

;;; ;   outut
        ;; mov eax, 4          ; system_write
        ;; mov ebx, 1          ; stdout
        ;; mov ecx, [ans]     ; move biggest element to accumulator
        ;; add ecx, 30h        ; convert to ascii representation
        ;; mov [buff], ecx     ; move to memory
        ;; mov ecx, buff       ; put pointer in ecx for printing
        ;; mov edx, 4          ; size, 4 bytes
        ;; int 80h             ; sytem call.

                    inc esi
                    jmp label1
label3:

exit:
                    mov eax, 1
                    mov ebx, 0
                    int 80h

which_is_larger_procedure:

;;; ;  Body
                    push ebp
                    mov ebp, esp
                    sub esp, 8

                    push eax
                    push ebx

                    mov ecx, [ebp 8]
                    mov edx, [ebp 12]

                    mov eax, [ecx]
                    mov ebx, [edx]



                     cmp al, bl
                     jg CL_g_DL
                     cmp byte[largest], bl
                     jg skip
                     mov byte[largest], bl

AL_g_BL:                        ;If AH is Larger than BL
                     cmp byte[largest], al
                     jg skip
                     mov byte[largest], al

label5:

skip:
;;; ; ;   outut
                    mov eax, 4   ; system_write
                    mov ebx, 1   ; stdout
                    mov ecx, [largest] ; move biggest element to accumulator
                    add ecx, 30h              ; convert to ascii representation
                    mov [buff], ecx    ; move to memory
                    mov ecx, buff      ; put pointer in ecx for printing
                    mov edx, 4        ; size, 4 bytes
                    int 80h           ; sytem call.



;;; ;  Outout
                     mov eax, 4  ; system_write
                     mov ebx, 1  ; stdout
                     mov ecx, msg1 ; put pointer in ecx for printing
                     int 80h      ; sytem call.


                    pop ecx
                    pop edx
                    add esp, 8
                    pop ebp
                    ret
  

Часть кода немного унаследована от экспериментов с тем, почему его сегментирование,

Следовал этому руководству: учебное пособие

Комментарии:

1. Конечно, вы пытались запустить это в отладчике, нет? В какой инструкции происходит ошибка сегментации?

2. Я не знаю ни одного отладчика, который работает с nasm, у вас есть какие-либо предложения?

3. Все они. Отладчикам все равно, как вы создали двоичный исполняемый файл. Любой (например, gdb) с радостью разберет все, что вы ему дадите, и позволит вам пошагово выполнять инструкцию за инструкцией.

4. Также проверьте edb, отладчик Evans.

Ответ №1:

Пока я пытался выяснить, как использовать GDB для его отладки, друг, который просматривал мой код, понял проблему.

                 mov eax, [ecx]
                mov ebx, [edx]
  

Проблема здесь заключалась в том, что я разыменовывал регистры, которые содержали фактические данные, а не адреса памяти, на данные, простым удалением скобок проблема была решена.

                 mov eax, ecx
                mov ebx, edx
  

Так и должно быть.