2010-11-16 2 views

ответ

0

Не уверен, что вы имели в виду, а так как ваш тег - 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 

Это то, что вы имели в виду с вопросом?

1

Соглашение о вызове «stdcall» гарантирует, что функция не испортит никаких регистров, кроме eax, edx, ecx. Если вы хотите сохранить edx и ecx - напишите макрос.

+0

Есть ли способ заставить eax автоматически сохранять и затем автоматически восстанавливать во время INVOKE? – Jumbo

+0

@Jumbo вы можете написать макрос, чтобы сохранить его, но когда вы его восстановите, вы потеряете возвращаемое значение функции. – Abyx

+0

stdcall фактически не гарантирует что-либо в MASM. Это могло бы в лучшем случае предположить, что функция должна вести себя таким образом. Чтобы регистры автоматически сохранялись/восстанавливались, вы должны использовать директиву USES в определении PROC. См. Мой ответ. – filofel

2

Посмотрите на пример, который я разместил там: selection sort in assembly language

использований директива в целевом PROC является то, что вы ищете.
ИСПОЛЬЗОВАНИЕ EAX ESI EDI автоматически сохраняет эти регистры после входа PROC и восстанавливает их при выходе (даже если у вас есть несколько точек RET и даже если не рекомендуется иметь несколько точек возврата). IOW, он будет генерировать PUSHes при входе PROC и согласованном (обратном порядке) POP перед каждым RET. Идея состоит в том, что, поскольку это сборка, вы полностью контролируете и отвечаете за те регистры, которые вы изменяете и хотите сохранить.
И вопреки тому, что было предложено в другом месте, объявление stdcall не сохраняет ничего автоматически для вас в MASM. Он просто определяет, будет ли вызывающий (код, сгенерированный для INVOKE), или вызываемый (код, сгенерированный в PROC) POPs parms.

+0

Этот вопрос касается 'invoke', а не' proc'. Или вы имеете в виду, что вы можете использовать 'uses' с' invoke'? – Abyx

+0

Единственное использование INVOKE - вызов PROC с соглашением о вызовах, parms и т. Д. – filofel

+0

INVOKE - это оболочка HLL вокруг вызова, обработка вызова, парм и т. Д. Расширения INVOKE и PROC - это две стороны одной и той же монеты. Например, в соответствии с типом proc, parms будут удалены вызывающим абонентом (по возвращении, таким образом генерируемым INVOKE) или вызываемым пользователем (внутри proc непосредственно перед каждым RET). Существует и не может быть другого способа автоматического сохранения/восстановления regs в MASM, но этот. В противном случае, это вручную, для каждого вызова, путем PUSHing перед вызовом и POPping при возврате. – filofel