Почему я получаю SIGSEGV с этим безусловным прыжком?

Я попытался запустить этот код в Linux, чтобы увидеть, что произойдет:

int fn(void) { return 0; }
int main(void) { __asm__("jmp fn;"); }

Я не вижу никаких причин для прекращения выполнения SIGSEGV, но это то, что я получаю. Я ожидал, что поток будет перенаправлен на _start поскольку стек никак не изменяется внутри main а также fn и обратный адрес внутри записи активации должен быть "пригодным для использования".

Не могли бы вы объяснить, что за этим стоит?

1 ответ

Решение

return 0 генерирует что-то вроде

mov $0x0, %eax
ret

где ret выскакивает адрес возврата из стека и переходит туда. Просто jmp не выдвигает обратный адрес, поэтому ret выскочит все, что находится в стеке.

Другие вопросы по тегам