Что такое порядок толчка аргументов - PullRequest
9 голосов
/ 04 февраля 2012

Я изучаю ассемблер. Что именно является порядком толчка аргумента? Я понимаю, как аргументы помещаются в стек, но что означает левая и правая части? слева или справа от чего? Или это просто связано с тем, как команда семантически написана, т.е.

mov ebp, esp; esp перемещается в ebp, справа налево.

Это правильно, или кто-то может просветить меня?

Большое спасибо!

Ответы [ 2 ]

14 голосов
/ 04 февраля 2012

Процессор не знает «аргументов функции».Поэтому, когда вы хотите написать f(a,b,c), вам действительно нужно выдвинуть аргументы «куда-нибудь».

Это соглашение.Я знаю, что на большинстве компьютеров x86 аргументы функции помещаются в стек справа налево, то есть сначала c, затем b, затем a.

push c
push b
push a
call f

Теперь вызываемая функция может использовать ebx -1 для, ebx - 2 для b и ebx - 3 для c.

Можно также установить соглашение, которое гласит: первые два аргумента находятся в регистрах ebx и ecx, остальные находятся в стеке.Пока звонящий и вызываемый абонент согласны, с тобой все в порядке.

10 голосов
/ 04 февраля 2012

В дополнение к объяснению xtofl вы можете взглянуть на эту таблицу x86 соглашений о вызовах . Что касается порядка аргументов, вы заметите, что почти все аргументов помещаются справа налево (крайний правый аргумент помещается первым), за исключением Pascal.

Другой сценарий, который xtofl не охватывает, это аргументы регистров - некоторые ABI требуют, чтобы некоторые аргументы были в регистрах , а не в стеке. Например, в системе x86_64 функция:

int add3(int a, int b, int c)

поставит аргументы:

a -> rdi
b -> rsi
c -> rdx

В частности, это будет выглядеть (синтаксис Intel):

mov     rdi, [source-of-a]
mov     rsi, [source-of-b]
mov     rdx, [source-of-c]
call    add3

Таким образом, регистры заполняются из списка регистров слева направо , а затем используется стек справа налево .

Как говорит xtofl, не имеет значения, что вы делаете, при условии, что вызывающий и вызываемый абоненты согласны - однако, ясно, что если вызывающий и вызываемый не согласны , это вызовет проблемы несовместимости, и это на самом деле проблема не только для ассемблера, но и для языков более высокого уровня - к счастью, компиляторы в основном работают справа налево. Для дальнейшего чтения вам может показаться интересной очистка стека для вызывающих и вызывающих абонентов - и обратите внимание, как он был стандартизирован для одного метода для x86_64.

.

Вы не говорите, что используете x86 - ваша архитектура наверняка будет иметь стандартное соглашение о вызовах, так как работать без него сложно.

...