Меня интересует, что происходит при выполнении команды call
кода сборки Visual C++ скомпилирован. Я думаю, что сама команда вызова подталкивает весь контекст в стек (регистрировать содержимое, ПК, ...) и обновляет ПК. Но опять же, я задаюсь вопросом, не сдвинут ли весь контекст или нет. Во многих случаях не все регистры используются в вызываемой функции. Компилятор обнаружил это и только нажал контекст, который был изменен функцией, или подталкивает весь контекст, реализованный так дешево на аппаратном уровне, который он всегда делает?Вызывается ли вызов функции сборки, чтобы все регистры были вставлены в стек?
ответ
Инструкция CALL
не толкает регистры в стеке. Он толкает только адрес, где должна возвращаться функция.
Инструкция INT
(которая действует аналогично вызову) также подталкивает содержимое регистра FLAGS
.
Если программа нуждается в некоторых других регистров, которые будут сохранены во время вызова функции, он должен хранить эти регистры в стеке явныхpush
инструкций, а затем восстановить их pop
инструкции.
Что нужно хранить и как именно, когда речь идет о языках высокого уровня, зависит только от компилятора. Компиляторы могут использовать любое соглашение, но обычно они придерживаются стандартного соглашения, чтобы обеспечить возможность связывания модулей, написанных на разных языках.
В программировании сборки стратегия сохранения полностью зависит от программиста. Он может использовать некоторые стандартные соглашения или пользовательские соглашения в зависимости от своих целей программирования.
Это все зависит от ABI (Application Binary Interface), который диктует, вызывает ли вызывающий или вызываемый сигнал вещи в стек. Поскольку вы не указали платформу (хотя для Visual Studio подразумевается x86), ответ зависит.
В общем случае вызывающий абонент не может знать, что вызовет вызываемая функция, поэтому компилятор не может оптимизировать на основе информации внутри функции.
Как правило, нажатие контекста на стек не выполняется автоматически на любой платформе, но на нескольких платформах есть макросы и оптимизированные инструкции, чтобы сделать это быстро. Обычно единственное, что автоматически выталкивается и выталкивается из стека, - это ПК.
Редактировать: для x86 существует несколько ABI. Вы должны проверить это Wiki reference, чтобы увидеть их всех (cdecl, stdcall и т. Д.). Каждый из них имеет разные правила о том, сохраняет ли вызывающий объект или вызываемый вызов контекст.
Я использую x86 да. Когда у меня есть вызов функции, который переводится только на ассемблерный код «call ...». Мне интересно, почему я не вижу, чтобы что-то попало в стек. Вызывается ли ПК инструкцией «вызов»? Как насчет флагов, они также попадают в стек? Может быть, это потому, что Visual Studio оптимизирует или отвечает за все это? –
Прочтите здесь подробное описание инструкций x86: http://x86.renejeschke.de/ – Downvoter
@ ClickyButton.com Я обновил ответ ссылкой на соглашения о вызовах x86. –