Ошибка сегментации сравнения матрицы сборки - PullRequest
2 голосов
/ 07 ноября 2011

Моя цель - загрузить значения в матрицу 5x5, сравнить каждое значение и распечатать наибольшее число.

После запуска отладчика я получаю:

0x080480bb <+0>:     mov    esi,DWORD PTR [eax+edi*1]

0x080480be <+3>:     jmp    0x804809d <loop>


segment .data
    matrix db   1,62,3,44,35, \
            61,52,43,45,55, \
            17,23,37,74,65, \
            13,12,93,94,95, \
            31,21,13,14,25

segment .bss

holder  resb    4

counter resb    4


segment .text

global _start

_start:

    mov eax, matrix
    call big

big:
    mov esi, holder
    mov edi, counter
    mov edi, 0
    jmp switch

loop:
    inc edi
    cmp esi, [eax + edi]
    jg switch
    cmp edi, 25 
    jle loop
    mov eax, [esi]
    sub eax, '0'
    mov eax, 4              
    mov ebx, 1
    mov ecx, esi
    mov edx, 4
    int 0x80

switch:
    mov esi, [eax + edi]
    jmp loop

exit:
    mov eax, 1
    xor ebx, ebx
    int 0x80

1 Ответ

1 голос
/ 07 ноября 2011

Я вижу некоторые проблемы в вашем коде. Вот первый:

cmp edi, 25 
jle loop
mov eax, [esi]   <--
sub eax, '0'
mov eax, 4 

На данный момент вы проверили всю матрицу и хотите записать наибольшее найденное значение, которое уже есть в esi, поэтому вам не нужно разыменовывать, чтобы получить его. Кроме того, вы должны добавить '0' для чисел от 0 до 9, поэтому преобразование также неверно. И, наконец, после преобразования вы перезаписываете значение в eax, которое поэтому теряется.
Однако здесь происходит настоящая ошибка сегментации,

mov esi, [eax + edi]   <--
jmp loop

Сразу после того, как вы напишите результат. Проблема в том, что ecx должен содержать указатель на строку с нулем в конце для записи. Вместо этого вы вводите число, которое хотите написать, что является неопределенным поведением (это означает, что все может произойти). Теперь eax содержит возвращаемое значение записи, поэтому я предполагаю, что произошла ошибка, и теперь eax содержит -1, что приводит к сегментированию. неисправность.
Одним из простых способов решения этой проблемы является добавление выхода jmp после записи значения.

И, наконец, что не менее важно (и, как сказал @ user786653), «неправильная обработка данных размером в байт». Что это значит? По сути, ваша матрица представляет собой массив байтов, но каждый раз, когда вы читаете из памяти, вы выбираете 4 байта за раз. Самое простое решение - объявить вашу матрицу в виде массива двойных слов (dd или dword вместо db) и умножить на 4 смещение (пример: mov eax, [ebx + ecx * 4]).

Да ладно, не волнуйся! Сборка - трудный зверь, с которым можно играть;)

EDIT:
Часть, которая находит наибольшее число, является правильной. Вы просто должны исправить часть «output» и адресацию, о которой я говорил ранее. По моему мнению, если вы используете шестнадцатеричное основание для своих чисел, преобразование его в печатную строку будет намного проще (вы можете умножить на 2 ^ n, сдвинув влево на n мест -> shl eax, 5 = eax * = 32)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...