Посмотрите на это из контекста , вызывающего эта функция. Код, который делает это выглядит примерно так:
caller+...: push argN
caller+...: ...
caller+...: push arg0
caller+...: call func
т.е. аргументы помещаются в стек в таком порядке, что на входе в func()
, стек будет иметь следующую структуру:
[esp+(N*4)] : argN
... : arg(N-1)...arg2
[esp+4 ] : arg1
[esp ] : <return address to caller()+...>
Тогда вы выполняете push %ebp; mov %esp, %ebp
последовательность, которая изменяет %esp
(от -4), так что ваш макет сейчас:
[ebp+4+(N*4)][esp+(N*4)] : argN
... : arg(N-1)...arg2
[ ebp+8 ][esp+8 ] : arg1
[ ebp+4 ][esp+4 ] : <return address to caller()+...>
[ ebp ][esp ] : <saved %ebp of caller>
Затем код выталкивает еще несколько регистров в стеке - так как это увеличивается каждый раз, когда %esp
изменяется на -4. В конечном счете (который вы не показали при разборке, но он будет там), вы получите инструкцию subl $..., %esp
. Это то, что выделяет пространство для ваших локальных переменных.Окончательный вариант стека что-то вроде:
[ebp+4+(N*4)][ ] : argN
... : arg(N-1)...arg2
[ ebp+8 ][ ] : arg1
[ ebp+4 ][ ] : <return address to caller()+...>
[ ebp ][ ] : <saved %ebp of caller>
[ ebp-4 ][ ] : <saved %ebx of caller>
[ ebp-8 ][ ] : ...
... : region for local variables
[ ebp-?? ][ esp ] : end of stack for func()
Любой адрес между [esp ... ebp-4]
находится в пределах того, что называется фрейм стека для функции и содержит либо регистр сохраненную от имени вызывающего абонента (например, ebx
в случае с дизассемблирование, показанное вами) или локальные переменные.
Следовательно, если в вашем коде вы видите любой доступ к %ebp - XX
, он находится в локальном переменном пространстве, если вы видите %ebp + YY
, он находится в пространстве, содержащем аргументы функции.
И причина, по которой они это делают, заключается в том, что аргументы всегда могут ссылаться на одно и то же смещение ebp. Вы не можете использовать esp для этой цели, потому что этой функции, возможно, потребуется использовать указатель стека для временных инструкций push/pop. –