Есть ли какое-либо условие, при котором адрес возврата не помещается в стек во время вызова функции в архитектуре x86?
Инструкция CALL ВСЕГДА помещает адрес, указанный EIP, в стек?
Ответы (1)
№ CALL
по определению поместит адрес возврата в стек перед переходом к целевому адресу. Этот адрес возврата равен EIP
(или RIP
) + sizeof(call instruction)
(обычно 5 байт).
В томе 2 Руководства разработчика программного обеспечения для архитектур Intel® 64 и IA-32 говорится, что CALL
:
Сохраняет информацию о связывании процедуры в стеке и переходах к вызываемой процедуре, указанной с помощью целевого операнда.
Это включает:
- Near Call — «вызов процедуры в текущем сегменте кода», когда EIP помещается в стек.
- Дальний вызов — «Вызов процедуры, расположенной в сегменте, отличном от текущего сегмента кода», где CS, EIP помещаются в стек.
Альтернативой, не отправляющей адрес возврата, является JMP
.
Каждый компилятор C, с которым я знаком, всегда реализует вызовы функций на x86 с помощью инструкции CALL
, за одним исключением: вызов хвоста , который можно реализовать с помощью файла JMP
. Особенно это происходит, когда одна функция возвращает результат вызова другой функции. Например.
int bar(int a, int b);
int foo(int a, int b)
{
if (a < b)
return 0;
return bar(a, b); // Will probably be: jmp bar
}
call
, вы можете выполнить хвостовой вызов с помощьюjmp
, который ничего не нажимает. - person Peter Cordes   schedule 14.04.2021