Единственный параметр, который она от нас требует - указание, на какое устройство мы желаем получить "квиток"-хендл. Вот табличка:
Хэндл стандартного ввода | -10 |
Хэндл стандартного вывода | -11 |
Хэндл "ошибок" | -12 |
Что нам нужно? Вывести строчку! Значит - запрашиваем хэндл для стандартного вывода, то есть перед вызовом функции "суем" в стек -11. После выполнения функции регистр EAX содержит столь желанный "хэндл стандартного вывода". Кладем этот хэндл в переменную hStdout (которую мы столь предусмотрительно определили на бряке 1) для последующего использования.
- Это ж что за безобразие? - воскликните вы. - Что это за таблица такая нездоровая? Какие-то отрицательные числа, которые ни в жисть не запомнить! Хотим таблицу как в MSDN'е! Чтобы не -10, -11, -12, а длинные мнемонические STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE!
Спокойно! Исходник, который мы сейчас рассматриваем, весьма точно отображает реальные процессы, происходящие в программе. Чуть позже мы приведем его к варианту в стиле Cи и посмотрим, как можно использовать некоторые высокоуровневые конструкции, значительно облегчающие жизнь низкоуровневому программисту.
Бряк 4. Ну наконец-то, самое главное - функция, которая, собственно, и выводит на консоль строку символов. Вот ее описание: BOOL WriteConsole( HANDLE hConsoleOutput, // handle to screen buffer CONST VOID *lpBuffer, // write buffer DWORD nNumberOfCharsToWrite, // number of characters to write LPDWORD lpNumberOfCharsWritten, // number of characters written LPVOID lpReserved // reserved );
Расшифровываем. Перед вызовом функции WriteConsole мы должны поместить в стек целых пять параметров: