Вот простая программа на C, для которой я использовал gdb, чтобы разобрать ее, чтобы понять, что происходит.GDB разобрать для простой программы
#include <stdio.h>
#include <string.h>
int main(){
printf("%d", sizeof(foo("HELLOWORLD")));
}
int foo(char* c)
{
printf("%s\n",c);
}
И ниже соответствующий код сборки для разборки главного
0x08048414 <+0>: push %ebp
0x08048415 <+1>: mov %esp,%ebp
0x08048417 <+3>: and $0xfffffff0,%esp
0x0804841a <+6>: sub $0x10,%esp
0x0804841d <+9>: mov $0x8048520,%eax
0x08048422 <+14>: movl $0x4,0x4(%esp)
0x0804842a <+22>: mov %eax,(%esp)
0x0804842d <+25>: call 0x8048320 <[email protected]>
0x08048432 <+30>: leave
0x08048433 <+31>: ret
И ниже демонтирует Foo
0x08048434 <+0>: push %ebp
0x08048435 <+1>: mov %esp,%ebp
0x08048437 <+3>: sub $0x18,%esp
0x0804843a <+6>: mov 0x8(%ebp),%eax
0x0804843d <+9>: mov %eax,(%esp)
0x08048440 <+12>: call 0x8048330 <[email protected]>
0x08048445 <+17>: leave
0x08048446 <+18>: ret
Я запутался об этих инструкциях:
0x08048417 <+3> and $0xfffffff0,%esp
Почему указатель стека должен быть выровнен, если он не был изменен раньше?0x0804841a <+6>:sub $0x10,%esp
Что именно эта инструкция делает особенно для программы?0x0804841d <+9>:mov $0x8048520,%eax
Что это за инструкция, относящаяся к программе?mov %eax,(%esp)
Что такое скобки вокруг%esp
означает?
Было бы полезно, если бы кто-то объяснил это.
1) выравнивание стека, 2) резервное пространство в стеке, 3) адрес «мир привет», 4) см. Соглашения о вызовах. –
Почему именно 16 байтов? – Dhatri
Выравнивание Wrt: вы не знаете, где указатель был раньше. Скобки в скобки, они похожи на '*' для C-указателей. –