Вызов FormatMessageA из 64-битной программы на ассемблере

Я несколько дней работал над подпрограммой ассемблера для вызова функции Windows API FormatMessageA, и я думаю, что у меня должно быть какое-то систематическое недопонимание. Мой распорядок показан ниже. Я проследил это в режиме отладки и знаю, что в момент вызова функции: 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

0 ответов

Другие вопросы по тегам