Повторить незаконную инструкцию

Я работаю над проектом, который реализует функцию в сборке, которая вызывается в файле main.c. Объявление функции подписи в C: void strrev(char *str) ; Инструкция Ret дает мне недопустимую ошибку инструкции. Почему? Я делаю это впервые.

Попытка опубликовать только соответствующий код:

SECTION .text
        global strrev

strrev:
        push    ebp
        mov     ebp, esp

        push    esi
        push    edi
        push    ebx

// doing things with al, bl, ecx, edi, and esi registers here


// restore registers and return    
        mov     esp,    ebp
        pop     ebx
        pop     edi
        pop     esi
        pop     ebp

        ret

Ошибка:

(gdb)
Program received signal SIGILL, Illegal instruction.
0xbffff49a in ?? ()

Компиляция и компоновка таким образом:

nasm -f elf -g strrepl.asm
nasm -f elf -g strrev.asm
gcc -Wall -g -c main7.c
gcc -Wall -g strrepl.o strrev.o main7.o

person b15    schedule 12.04.2013    source источник
comment
Внимательно наблюдайте в отладчике, что извлекается и куда вы возвращаетесь.   -  person Raymond Chen    schedule 12.04.2013


Ответы (1)


mov esp, ebp изменяет esp, чтобы указать, где он был, когда mov ebp, esp был выполнен. Это было до того, как вы поместили esi, edi и ebx в стек, так что вы больше не можете их извлекать. Поскольку вы это делаете, стек неверен, и ret не работает так, как хотелось бы.

Вероятно, вы можете удалить инструкцию mov esp, ebp. Подобное восстановление указателя стека необходимо только в том случае, если в подпрограмме есть переменные изменения указателя стека (например, чтобы переместить стек в желаемое выравнивание или освободить место для массива переменной длины). Если ваш стек обрабатывается просто, то вы просто выталкиваете в обратном порядке то, что вы нажимаете. Если у вас есть изменения переменных в стеке, вам нужно восстановить указатель в другое место, а не в ebp, которое вы сохранили, чтобы вы могли извлекать ebx, edi и esi.

person Eric Postpischil    schedule 12.04.2013
comment
Попался, имеет смысл, я думаю. Я посмотрю на это дальше, когда я вернусь домой. - person b15; 12.04.2013
comment
Теперь он прошел возврат, но когда программа main.c начинает печатать строки, которые я перевернул, она печатает пустые строки. - person b15; 12.04.2013