Можно ли автоматически сохранять регистры процессора, когда я использую директиву Invoke в masm?INVOKE MASM автоматически сохраняет регистры?
ответ
Не уверен, что вы имели в виду, а так как ваш тег - masm32, я буду считать Windows x86.
Что совершенно возможно, это нажать все аргументы, которые требуется вызвать API-вызову, а затем просто вызвать нужную функцию. Я имею в виду, что, когда вы прощаете в сборке для Windows, вам не нужно использовать регистры для «вызова» API-интерфейсов, вам нужно нажать на аргументы, а затем вызвать (или вызвать) API.
Например, это:
push 0
push DWORD PTR SS:[EBP+8]
push 0
push 0
push 80000000h
push 80000000h
push 80000000h
push 80000000h
push 0CF0000h
push offset AppName
push offset ClassName
push 0h
call CreateWindowExA
точно равно это (на самом деле только значения параметров различны):
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
Это то, что вы имели в виду с вопросом?
Соглашение о вызове «stdcall» гарантирует, что функция не испортит никаких регистров, кроме eax, edx, ecx. Если вы хотите сохранить edx и ecx - напишите макрос.
Посмотрите на пример, который я разместил там: selection sort in assembly language
использований директива в целевом PROC является то, что вы ищете.
ИСПОЛЬЗОВАНИЕ EAX ESI EDI автоматически сохраняет эти регистры после входа PROC и восстанавливает их при выходе (даже если у вас есть несколько точек RET и даже если не рекомендуется иметь несколько точек возврата). IOW, он будет генерировать PUSHes при входе PROC и согласованном (обратном порядке) POP перед каждым RET. Идея состоит в том, что, поскольку это сборка, вы полностью контролируете и отвечаете за те регистры, которые вы изменяете и хотите сохранить.
И вопреки тому, что было предложено в другом месте, объявление stdcall не сохраняет ничего автоматически для вас в MASM. Он просто определяет, будет ли вызывающий (код, сгенерированный для INVOKE), или вызываемый (код, сгенерированный в PROC) POPs parms.
Этот вопрос касается 'invoke', а не' proc'. Или вы имеете в виду, что вы можете использовать 'uses' с' invoke'? – Abyx
Единственное использование INVOKE - вызов PROC с соглашением о вызовах, parms и т. Д. – filofel
INVOKE - это оболочка HLL вокруг вызова, обработка вызова, парм и т. Д. Расширения INVOKE и PROC - это две стороны одной и той же монеты. Например, в соответствии с типом proc, parms будут удалены вызывающим абонентом (по возвращении, таким образом генерируемым INVOKE) или вызываемым пользователем (внутри proc непосредственно перед каждым RET). Существует и не может быть другого способа автоматического сохранения/восстановления regs в MASM, но этот. В противном случае, это вручную, для каждого вызова, путем PUSHing перед вызовом и POPping при возврате. – filofel
Есть ли способ заставить eax автоматически сохранять и затем автоматически восстанавливать во время INVOKE? – Jumbo
@Jumbo вы можете написать макрос, чтобы сохранить его, но когда вы его восстановите, вы потеряете возвращаемое значение функции. – Abyx
stdcall фактически не гарантирует что-либо в MASM. Это могло бы в лучшем случае предположить, что функция должна вести себя таким образом. Чтобы регистры автоматически сохранялись/восстанавливались, вы должны использовать директиву USES в определении PROC. См. Мой ответ. – filofel