Не могу найти в чем ошибка. "Вывод на экран чисел от 1 до 10" - Assembler
Формулировка задачи:
Пока только начал изучать язык Ассемблера и уже столкнулся с проблемой. Обучаюсь по книге "Изучаем Ассемблер - Крупник А.Б." пишу листинг программы как в книге (листинг 4.3)Программа выполняется правильно, однако результат не выводится на экран, при асемблировании ни каких ошибок не выдает, я уже не знаю что и делать. Если кого не затруднит - помогите начинающему)
Вот сам листинг:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\user32.lib
BSIZE equ 15
.data
ifmt BYTE "%d",0
buf BYTE BSIZE dup (?)
crlf BYTE 0dh,0ah
stdout DWORD ?
cWritten DWORD ?
.code
start:
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov edx,1
mov ecx,10
nxt:
push ecx
push edx
invoke wsprintf, ADDR buf,ADDR ifmt,edx
invoke WriteConsoleA,stdout,ADDR buf,BSIZE,ADDR cWritten,NULL
invoke WriteConsoleA,stdout,ADDR crlf,2,ADDR cWritten,NULL
pop edx
inc edx
pop ecx
loop nxt
invoke ExitProcess,0
end startРешение задачи: «Не могу найти в чем ошибка. "Вывод на экран чисел от 1 до 10"»
textual
Листинг программы
; masm windows console # .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib BSIZE equ 15 .data ifmt BYTE "%d",0Ah,0Dh,0 buf BYTE BSIZE dup (?) .code start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov ebx,eax mov edx,1 mov ecx,10 @@: push ecx push edx invoke wsprintf, ADDR buf,ADDR ifmt,edx invoke WriteConsoleA,ebx,ADDR buf,BSIZE,esp,NULL pop edx inc edx pop ecx loop @b invoke Sleep,5000 invoke ExitProcess,0 end start
Объяснение кода листинга программы
- Описание постановки задачи: задача заключается в выводе на экран чисел от 1 до 10.
- Описание работы кода:
- Код начинается с директивы .386, которая задает модель процессора.
- Затем идет директива .model flat, stdcall, которая определяет модель памяти и указывает, что все функции ассемблера должны использовать стандартный вызов.
- Далее идут директивы include, которые подключают необходимые заголовочные файлы.
- Определены две переменные: BSIZE (размер буфера) и ifmt (формат вывода числа).
- Затем определена переменная buf (буфер) размером BSIZE, заполненная символами вопроса.
- В блоке .code находится точка входа в программу start.
- Функция GetStdHandle получает дескриптор стандартного вывода.
- Затем происходит перемещение дескриптора в регистр ebx.
- Переменная edx инициализируется значением 1.
- Переменная ecx инициализируется значением 10.
- Затем начинается цикл, который выполняется 10 раз.
- В начале цикла на стек помещаются значения ecx и edx.
- Функция wsprintf форматирует строку в формате ifmt и записывает ее в буфер buf.
- Затем функция WriteConsoleA записывает содержимое буфера в стандартный вывод.
- После этого значение edx увеличивается на 1.
- Значение ecx уменьшается на 1.
- Если ecx больше или равно нулю, то происходит выход из цикла.
- В конце программы вызывается функция Sleep, которая приостанавливает выполнение программы на 5 секунд.
- Затем вызывается функция ExitProcess, которая завершает работу программы.
- Ошибки в коде:
- Ошибка в определении размера буфера (переменная BSIZE). Размер буфера должен быть достаточным для хранения отформатированного числа, включая символ '\0'. В данном случае, размер буфера равен 15, что может привести к переполнению буфера при форматировании чисел от 1 до 10.
- Отсутствует проверка на достаточность размера буфера при вызове функции WriteConsoleA. Если отформатированное число больше размера буфера, то произойдет переполнение буфера, что может привести к непредсказуемому поведению программы.