Недопустимая инструкция gcc ассемблер - PullRequest
1 голос
/ 16 мая 2010

В ассемблере:

.globl _test

_test:

pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax

pushl %eax
call printf

popl %ebp
ret

Звонок с c

main()
{
  _test("Hello");
}

Компиляция:

gcc -m32 -o test test.c test.s

Этот код иногда дает мне недопустимые инструкции, а в другом случае сегментирует ошибку. В gdc я всегда получаю недопустимые инструкции, это всего лишь простой тест, у меня была большая программа, которая работала, и внезапно после того, как ни одна причина не перестала работать, теперь я всегда получаю эту ошибку, даже если начинаю с нуля, как описано выше.

Я сузил его до pushl% eax и вызову printf, если я закомментирую эти строки, код работает нормально.

Есть идеи? (Я запускаю программу в своем кластере linux университетов, поэтому я не изменил никаких настроек ..)

Ответы [ 2 ]

3 голосов
/ 16 мая 2010

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

Вы делаете pushl %eax (или любой другой регистр), а затем делаете popl %ebp. Эти два вместе имеют тот же эффект, что и movl %eax, %ebp.

Я предполагаю, что вы пытаетесь вернуть значение, хранящееся в eax. В соглашении о вызовах C eax используется для возвращаемых значений, поэтому нет необходимости сдвигать его или делать с ним что-либо, просто оставьте значение в нем, и другой код его подберет. Если это не то, что вы пытаетесь сделать, то я озадачен тем, почему вы будете вставлять% eax в конце этой функции.

2 голосов
/ 17 мая 2010

Заменить всплывающую инструкцию на leave. Это восстанавливает указатель стека и базы.

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