Вызов WriteConsole через промежуточную функцию не работает должным образом

я пытаюсь выучить assembly, так что я вручную преобразование C а также C++ код для assembly код.

  • x86

  • Visual Studio

Преобразование вручную следующего C код для assembly код:

static HANDLE OUTPUT_HANDLE;

BOOL __stdcall InputConsole(const VOID *lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten)
{
WriteConsoleA(OUTPUT_HANDLE, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, 0);
}

int main()
{
DWORD charsWritten;
OUTPUT_HANDLE = GetStdHandle(STD_OUTPUT_HANDLE);InputConsole("Hello World!\n", 13, &charsWritten);
}
.586
.model flat, stdcall
.stack 4096

EXTRN   ExitProcess@4       :   PROC
EXTRN   GetStdHandle@4      :   PROC
EXTRN   WriteConsoleA@20    :   PROC

.data
STD_OUTPUT_HANDLE       DD  ?
WRITE_CONSOLE_STRING    DB  "Hello World!", 10, 0
CHARS_WRITTEN           DD  ?

.code

WriteConsole PROC
PUSH    0                   ; lpReserved

MOV     EAX, [ESP + 16]     ; lpNumberOfCharsWritten
PUSH    EAX

MOV     EAX, [ESP + 16]     ; nNumberOfCharsToWrite
PUSH    EAX

MOV     EAX, [ESP + 16]     ; lpBuffer
PUSH    EAX

PUSH    STD_OUTPUT_HANDLE   ; hConsoleOutput

CALL    WriteConsoleA@20

ADD     ESP, 12             ; Restore stack

RET
WriteConsole ENDP

main: NOP
PUSH    -11
CALL    GetStdHandle@4;
MOV     STD_OUTPUT_HANDLE, EAX

LEA     EAX, CHARS_WRITTEN
PUSH    EAX

PUSH    13

LEA     EAX, WRITE_CONSOLE_STRING
PUSH    EAX

CALL    WriteConsole

PUSH    0
CALL    ExitProcess@4
END main

На данный момент он печатает фактическую строку, однако Access Violation Exception брошен в ADD ESP, 12, После более тщательной проверки с помощью отладчика кажется, что я должен добавить 16 вместо 12 ESP, чтобы восстановить стек. Все еще после того, как сделать это 16 приложение замораживается после возвращения из procedure,

  • Почему мне нужно добавить 16 вместо 12 в то время как я помещаю только три 4-байтовых аргумента в стек?
  • Доступ к «входным аргументам» с помощью ESP + xx правильный путь?
  • Почему моя программа зависает, хотя я восстанавливаю стек и что-то на самом деле написано на консоли?
  • Есть ли другой способ «передать аргумент по ссылке» в assembly вместо использования глобального .data адрес?

Я знаю, что вы можете установить аргументы для процедуры в Visual Studio (какой IDE я пользуюсь), однако это должно быть возможно с тем, как я это делаю, верно?

0

Решение

Вы не делаете это с add esp Вы делаете это ret 12,
— Шут

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]