Функция для вывода сообщения в консоль - Assembler
Формулировка задачи:
В общем есть программа conout.asm
и программа simpmes.asm
собираю:
И ничегошеньки не работает. Подскажите, в чем проблема?
extern _lstrlenA@4 extern _WriteConsoleA@20 extern _GetStdHandle@4 global conout section .text conout: lea edi, [ebp+0x08] ;получить хэндл вывода push dword -11 call _GetStdHandle@4 mov ebx, eax ;длина строки push edi call _lstrlenA@4 mov edx, eax ;вывод на экран push dword 0 push eax push edx push edi push ebx call _WriteConsoleA@20 ret 4
extern conout global start section .data message db "Hello, world!", 0xA section .text start: push message call conout ret
nasm -f win32 conout.asm nasm -f win32 simmes.asm golink /console /entry start simmes.obj conout.obj kernel32.dll user32.dll
Решение задачи: «Функция для вывода сообщения в консоль»
textual
Листинг программы
extern _lstrlenA@4 extern _WriteConsoleA@20 extern _GetStdHandle@4 global conout section .text conout: mov edi, [esp+0x04] ;получить хэндл вывода push dword -11 call _GetStdHandle@4 mov ebx, eax ;длина строки push edi call _lstrlenA@4 mov edx, eax ;вывод на экран push dword 0 push eax push edx push edi push ebx call _WriteConsoleA@20 ret 4
Объяснение кода листинга программы
- extern _lstrlenA@4 — это функция, которая принимает в качестве аргумента адрес строки и возвращает её длину.
- extern _WriteConsoleA@20 — это функция, которая принимает в качестве аргументов дескриптор файла (в данном случае, стандартный вывод), адрес строки и её длину, и выводит указанную строку в консоль.
- extern _GetStdHandle@4 — это функция, которая возвращает дескриптор стандартного вывода (или другого указанного объекта).
- global conout — это определение глобальной функции с именем
conout
. - section .text — это секция, в которой размещается исполняемый код.
- conout: — это метка начала функции
conout
. - mov edi, [esp+0x04] — это пересылка в регистр edi адреса аргумента функции, который является указателем на строку для вывода.
- push dword -11 — это отправка в стек значения -11 (что соответствует дескриптору стандартного вывода).
- call _GetStdHandle@4 — это вызов функции _GetStdHandle с аргументом -11 и сохранение результата в регистре eax.
- mov ebx, eax — это перенос значения из регистра eax в регистр ebx, который будет использоваться как индекс стека.
- push edi — это отправка в стек адреса регистра edi.
- call _lstrlenA@4 — это вызов функции _lstrlenA с аргументом edi (адрес строки) и сохранение результата в регистре eax.
- mov edx, eax — это перенос значения из регистра eax в регистр edx, который будет использоваться для хранения длины строки.
- push dword 0 — это отправка в стек нулевого значения (что соответствует символу конца строки).
- push eax — это отправка в стек значения регистра eax (длина строки).
- push edx — это отправка в стек значения регистра edx (длина строки).
- push edi — это отправка в стек адреса регистра edi (адрес строки).
- push ebx — это отправка в стек значения регистра ebx (индекс стека).
- call _WriteConsoleA@20 — это вызов функции _WriteConsoleA с аргументами (дескриптор стандартного вывода, адрес строки, длина строки, символ конца строки, адрес строки, длина строки) и сохранение результата в регистре eax.
- ret 4 — это возврат из функции с указанием числа 4 в качестве значения, которое будет возвращено (это обычно используется для определения типа возвращаемого значения функции).