Сборка - неправильная реализация свободного списка - PullRequest
0 голосов
/ 12 марта 2012

Я читаю книгу, в которой приводим следующий пример: Существует список, в котором каждый член имеет адрес следующего члена в четырех первых байтах. Последний член имеет значение 0. Он говорит, что следующая реализация неверна, и я не понимаю, почему:

freeList
   mov eax, [ebp+8]
   cmp eax, 0
   jne cont
   ret
cont:
   mov ebx, [eax]
   mov [ebp+8], ebx
   push eax
   call free
   pop eax
   call freeList

(мне не нужна правильная реализация, у меня она есть. Мне просто нужно понять, что с ней не так)

Спасибо.

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

Последняя строка неверной реализации - call freeList.Но когда (рекурсивный) вызов завершится, он попытается вернуться к несуществующему коду после этой строки.Добавление инструкции ret сделает код работающим, но обычно вы пытаетесь избежать этого, за исключением случаев отладки кода, в этом случае иногда помогает увидеть все промежуточные вызовы.Вместо этого вы можете упростить call freeList; ret до простого jmp freeList.

Пример отладки высокоуровневого кода:

function freeList(list) {
    if (list) {
        var next = list->next;
        free(list);
        freeList(next);
    }
}

Если вы компилируете с оптимизацией, компилятор может захотеть написатьрекурсивный вызов freeList(next) путем копирования next в list и выполнения jmp, однако это уничтожит значение list.Это означает, что когда вы пытаетесь отладить функцию, вы не можете сказать, какие элементы списка уже были освобождены.Поэтому вы можете отключить эту оптимизацию, когда пытаетесь отладить проблему в функции.

0 голосов
/ 12 марта 2012

Предполагая, что это функция, невозможно вызвать ее напрямую, так как вам потребуется настроить кадр стека перед вызовом, а затем развернуть кадр после вызова. Он также не сохраняет EBX, что идет вразрез с большинством системных ABI (где только EAX, ECX и EDX являются чистыми регистрами)

если это встроенный код, то текущий кадр должен быть размотан (что не является).

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