Я не совсем понимаю строку с комментарием в ней ниже. Я прочитал несколько сообщений в SO и в руководстве gcc
и узнал, что он предназначен для выравнивания адресов стека, но не понимает, как он это делает. Код показан ниже:
Ответ 2
Похоже, что это часть некоторого кода для создания магазина в начале main
.
Начало функции: сохранить указатель базового фрейма в стеке (требуется команда leave
позже):
0x08048414 <+0>: push ebp
Теперь мы привязываем указатель стека к 16-байтовой привязке, потому что компилятор (по какой-либо причине) этого хочет. Это может быть так, что он всегда хочет иметь 16-байт выровненных кадров или что локальным переменным требуется выравнивание по 16 байт (возможно, кто-то использовал uint128_t
или они используют тип, который использует gcc vector extensions). В принципе, поскольку результат всегда будет меньше или равен текущему указателю стека, а стек растет вниз, он просто отбрасывает байты до тех пор, пока не достигнет 16-байтовой выровненной точки.
0x08048415 <+1>: mov ebp,esp
0x08048417 <+3>: and esp,0xfffffff0
Затем мы вычитаем 16 из указателя стека, создав 16 байтов локального пространства переменных:
0x0804841a <+6>: sub esp,0x10
puts((const char*)0x8048510);
0x0804841d <+9>: mov DWORD PTR [esp],0x8048510
0x08048424 <+16>: call 0x8048320 <[email protected]>
system((const char*)0x8048520);
0x08048429 <+21>: mov DWORD PTR [esp],0x8048520
0x08048430 <+28>: call 0x8048330 <[email protected]>
Выйдите из функции (см. другой ответ о том, что делает leave
):
0x08048435 <+33>: leave
0x08048436 <+34>: ret
Пример "отбрасывания байтов": скажем, esp = 0x123C в начале main
. Первые строки кода:
0x08048414 <+0>: push ebp
0x08048415 <+1>: mov ebp,esp
приведет к этой карте памяти:
0x123C: (start of stack frame of calling function)
0x1238: (old ebp value) <-- esp, ebp
Тогда:
0x08048417 <+3>: and esp,0xfffffff0
заставляет последние 4 бита esp равным 0, что делает это:
0x123C: (start of stack frame of calling function)
0x1238: (old ebp value) <-- ebp
0x1234: (undefined)
0x1230: (undefined) <-- esp
В этом случае программист не может полагаться на определенный объем памяти между esp
и ebp
; поэтому эта память отбрасывается и не используется.
Наконец, программа выделяет 16 байтов хранилища стека (локального):
Затем мы вычитаем 16 из указателя стека, создав 16 байтов локального пространства переменных:
0x0804841a <+6>: sub esp,0x10
дает нам это отображение:
0x123C: (start of stack frame of calling function)
0x1238: (old ebp value) <-- ebp
0x1234: (undefined)
0x1230: (undefined)
0x123C: (undefined local space)
0x1238: (undefined local space)
0x1234: (undefined local space)
0x1230: (undefined local space) <-- esp
В этот момент программа может быть уверена, что 16 байт с 16-байт выровненной памятью указывают на esp
.