Я работал в течение нескольких дней над подпрограммой ассемблера для вызова Windows API-функции FormatMessageA, и я думаю, что у меня должно быть систематическое c недоразумение. Моя рутина показана ниже. Я проследил это в режиме отладки, и я знаю, что в то время, когда вызывается функция: rcx имеет шестнадцатеричный 1B00, который является значениями флага, которые я указал (dwFlags); rdx имеет шестнадцатеричное 33, которое является фиктивным начальным дескриптором, который я подключил, чтобы спровоцировать ошибку (lpSource); r8 имеет 6, что является номером сообщения об ошибке, которое было возвращено GetLastError, что соответствует ERROR_INVALID_HANDLE (dwMessageId); r9 имеет 0 для языка по умолчанию (dwLanguageId); rsp + 32 имеет адрес msgptrp, который является моей областью для получения адреса сообщения об ошибке, выделенного вызываемой функцией (lpBuffer); rsp + 40 имеет шестнадцатеричное 28 или десятичное 40, что является минимальным количеством символов, которое я произвольно указал для сообщения об ошибке (nSize); и rsp + 48 имеет адрес argmntsp, который в соответствии с документацией должен игнорироваться с указанными мною флагами (* Аргументы).
Если есть проблема и, очевидно, так как rax возвращается как ноль, Я подозреваю, что это связано с lpBuffer, который, как говорится в документации, имеет тип данных LPTSTR, что бы это ни было. Иногда я хочу крикнуть: «Хорошо, это то, что с точки зрения C ++, но что это такое действительно ? Я надеюсь, что кто-то может легко определить, где я сбежал с рельсов, потому что я в своем уме покончим с этим, и это то, что мне нужно, чтобы начать эффективную проверку ошибок для моих будущих начинаний.
goterr PROC
;
.data
; flag values used:
; hex 00000100 FORMAT_MESSAGE_ALLOCATE_BUFFER
; hex 00000200 FORMAT_MESSAGE_IGNORE_INSERTS
; hex 00000800 FORMAT_MESSAGE_FROM_HMODULE
; hex 00001000 FORMAT_MESSAGE_FROM_SYSTEM
flagsp dd 00001B00h ; those flags combined
saveinitp dq ?
bmaskp dq 0fffffffffffffff0h
savshadp dq ?
msgptrp dq ?
handlep dd ?
argmntsp dd ?
;
.code
mov saveinitp, rsp ; save initial contents of stack pointer in this proc
sub rsp, 56 ; shadow space (max of 7 parameters * 8)
and rsp, bmaskp ; make sure it's 16 byte aligned
mov savshadp, rsp ; save address of aligned shadow area for this proc
;
mov handlep, ecx ; save passed I/O handle value locally
;
call GetLastError ; get the specific error
;
mov rsp, savshadp ; shadow area for this proc
mov ecx, flagsp ; flags for Windows error routine
mov edx, handlep ; handle passed from caller
mov r8d, eax ; msg id from GetLastError in low order dword
mov r9, 0 ; default language id
lea rax, msgptrp ; pointer to receive address of msg buffer
mov [rsp+32], rax ; put it on the stack
mov rax, 40 ; set lower doubleword to minimum size for msg buffer
mov [rsp+40], rax ; put it on the stack
lea rax, argmntsp ; variable arguments parameter (not used)
mov [rsp+48], rax ; put it on the stack
call FormatMessageA ; if rax eq 0 the called failed, otherwise rax is no chars.
mov rsp, saveinitp ; restore initial SP for this proc
ret
goterr ENDP