Ret незаконна инструкция

Работя с проект, който имплементира функция в асемблиране, която се извиква в 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