Можно ли автоматически сохранять регистры процессора, когда я использую директиву Invoke в masm?
ВЫЗЫВАТЬ MASM, сохраняя регистры автоматически?
Ответы (3)
Посмотрите на пример, который я разместил там: сортировка выбора на языке ассемблера
Директива USES в целевом PROC - это то, что вы ищете.
USES EAX ESI EDI автоматически сохранит эти регистры при входе в PROC и восстановит их при выходе (даже если у вас несколько точек RET и даже если имеется несколько точек ret не рекомендуется). IOW, он будет генерировать PUSH при вводе PROC и последовательно согласованные (в обратном порядке) POP перед каждым RET. Идея состоит в том, что, поскольку это сборка, у вас есть полный контроль и ответственность за те регистры, которые вы изменяете и хотите сохранить.
И вопреки тому, что было предложено где-то еще, объявление stdcall не сохраняет все автоматически для вас в MASM. Он просто определяет, отправляет ли вызывающий (код, сгенерированный для INVOKE) или вызываемый (код, сгенерированный в PROC) пармы.
invoke
, а не proc
. Или вы имеете в виду, что вы можете использовать uses
с invoke
?
- person Abyx; 22.11.2010
invoke GetCommandLine
, где proc
? Что сохранит мои реестры?
- person Abyx; 23.11.2010
Соглашение о вызове "stdcall" гарантирует, что функция не испортит регистры, кроме eax, edx, ecx. Если хотите сохранить edx и ecx - напишите макрос.
Не совсем уверен, что вы имели в виду, и поскольку ваш тег - 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
Это то, что вы имели в виду, задавая свой вопрос?