Я пишу функцию, использующую соглашение о вызовах cdecl, поэтому мне нужно убедиться, что состояние регистров сохраняется таким, каким оно было до вызова функции.
Как вы, наверное, знаете, вы можете делать с EAX, ECX и EDX все, что хотите, но вам нужно будет сохранить практически все остальное
Мой вопрос в том, как это обычно выполняется. Это просто вопрос помещения регистров в стек в начале функции и последующего извлечения их в регистры в конце функции?
Да, обычно так и делается. PUSH все в начале, POP перед возвращением.
Но иногда может иметь смысл использовать вместо этого регистр, сохраненный вызывающей стороной. Допустим, вы никогда не используете EDX в своей функции и не вызываете никакую функцию так, чтобы это могло затронуть ее содержимое. Но вы хотите использовать EDI в своей функции. Вы можете сохранить EDI в стеке или сохранить его в EDX.
mov edx, edi
; Do something with EDI without corrupting EDX, e.g. string manipulation
mov edi, edx
вместо
push edi
; Do something with EDI, e.g. string manipulation
pop edi
Использование регистров немного быстрее, чем использование стека, поэтому это может дать некоторые видимые улучшения производительности, если, например, вы используете эту функцию в цикле.
Обратите внимание, что вам не нужно необходимо сохранять все в самом начале и восстанавливать непосредственно перед возвратом. Вы можете сохранить регистр прямо перед тем, как использовать его, и восстановить его, как только закончите с ним работать, в середине функции.
person
tux3
schedule
08.01.2015