Я написал ниже код.
int main (int argc, char *argv[])
{
char *uargv[3];
uargv[0] = "echo";
uargv[1] = "hello!";
uargv[2] = 0;
exec("echo", uargv);
exit();
}
И скомпилирован с помощью gcc 5.4.
Ниже приведен ассемблерный код вышеуказанной программы.
0x00: lea 0x4(%esp),%ecx
0x04: and $0xfffffff0,%esp
0x07: pushl -0x4(%ecx)
0x0a: push %ebp
0x0b: mov %esp,%ebp
0x0d: push %ecx
0x0e: sub $0x14,%esp
0x11: movl $0x7c3,-0x14(%ebp)
0x18: movl $0x7c8,-0x10(%ebp)
0x1f: movl $0x0,-0xc(%ebp)
0x26: sub $0x8,%esp
0x29: lea -0x14(%ebp),%eax
0x2c: push %eax
0x2d: push $0x7c3
0x32: call 2ce <exec>
0x37: add $0x10,%esp
0x3a: call 296 <exit>
Я не могу понять три части приведенного выше ассемблерного кода.
Во-первых, в коде, который находится по адресам 0x00, 0x04, 0x07, 0x0a, 0x0b, 0x0d, работает следующим образом.
0x00: save ebp+4 to ecx, and it is address of argc.
0x04: align esp with 16 byte
0x07: push ecx-4 to stack, and it is return address.
0x0a ~ 0x0b: setup ebp
0x0d: push ecx to stack, and it is address of argc.
Интересно, почему он снова нажимает обратный адрес и почему он нажимает адрес argc.
Это был мой первый вопрос.
Во-вторых, он выделяет стек в инструкции 0x0e для локальной переменной uargv.
Однако размер uargv всего 12 байт.
Но он выделяет 20 байт.
Если это из-за выравнивания по 16 байтам, то почему локальные переменные сохраняются в esp+4, а не в esp (ebp+0x14 совпадает с esp+4).
В-третьих, почему инструкция 0x26 выделяет под стек больше 8 байт?
Больше места в стеке не требуется, потому что аргументы exec сохраняются в стеке командой push.
Спасибо.
main
, потому что компилятор не может полагаться на выравнивание входящего указателя стека, поэтому он выполняет выравнивание сам и помещает адрес возврата сверху. - person Jester   schedule 07.11.2018ecx
помещается, потому что это регистр, сохраняемый вызывающей стороной, и обычно он необходим для восстановления стека. Так как ваш код вызываетexit
, который здесь не используется. Расположение локальных переменных остается за компилятором. - person Jester   schedule 07.11.2018