3.1 Цель работы
Изучить технику создания и применения макросов. Научиться наблюдать за результатами работы макрогенератора, встроенного в ml.exe.
3.2 Выполнение программы
3.2.1 Макроопределение и макрорасширение
Макрогенератор выдал ошибку «error A2044: invalid character in file», поскольку нет поддержки кириллицы. Соответствующая ошибка была выведена и в консоль и в файл m1.lst.
Таблица 3.1 – Сравнение файлов m1.asm и m1.lst
m1.asm | m1.lst |
.486 .MODEL flat, stdcall ;точка1 – место макроопределений mdef MACRO ; Просто текст mov eax, edx; обычная команда ; с обычным комментарием ;; Скрытый комментарий push edx;; обычные pop esi;; команды endm .data ; точка2 - секция данных .code ; точка3 - секция кода mdef end | .486 .MODEL flat, stdcall ; точка1 - место макроопределений .data ; точка2 - секция данных .code ; точка3 - секция кода ; Просто текст mov eax, edx; обычная команда ; с обычным комментарием push edx pop esi end |
При макрорасширении обычные комментарии остались на прежних местах, скрытые комментарии были удалены. Также макрос был удален с места своего определения. Тело макроса заменило его вызов в файле m1.asm.
3.3.2 Повторение строк Repeat
В таблице 3.2 приводится содержимое файлов m2.asm и m2.lst.
Таблица 3.2 – Сравнение файлов m2.asm и m2.lst
m2.asm | m2.lst |
.486 .MODEL flat, stdcall ; точка1 - место макроопределений .data ; точка2 - секция данных A = 1 Massiv Label Word Repeat 10 Dw A*A A = A + 1 Endm .code ; точка3 - секция кода end | .486 .MODEL flat, stdcall ; точка1 - место макроопределений .data ; точка2 - секция данных A = 1 Massiv Label Word Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 Dw A*A A = A + 1 .code ; точка3 - секция кода end |
При макрорасширении команда Repeat была заменена десятком повторений тела команды
3.2.3 Цикл For
В таблице 3.2 приводится содержимое файлов m3.asm и m3.lst.
Таблица 3.2 – Сравнение файлов m3.asm и m3.lst
m3.asm | m3.lst |
.486 .MODEL flat, stdcall ; точка1 - место макроопределений .data ; точка2 - секция данных massiv label word for y, <1,4,9,16,25> dw y endm .code ; точка3 - секция кода For x,<1,3,5,7,9> mov eax, x endm end | .486 .MODEL flat, stdcall ; точка1 - место макроопределений .data ; точка2 - секция данных massiv label word dw 1 dw 4 dw 9 dw 16 dw 25 .code ; точка3 - секция кода mov eax, 1 mov eax, 3 mov eax, 5 mov eax, 7 mov eax, 9 end |
При макрорасширении цикл были заменены обычным повторением инструкций, которые описывались в теле цыклов.
3.2.4 Анализ расширенного листинга программы
Содержимое файла coff1.asm:
include \masm32\include\masm32rt.inc
; ИЗУЧЕНИЕ РАСШИРЕННОГО ЛИСТИНГА
; <1. Здесь можно описывать макросы.>
macrodef MACRO par1, par2, par3
LOCAL M3
mov par2, par1; обычная команда
; с обычным комментарием
;; Скрытый комментарий
M3:
push par3;; обычные
pop par2;; команды
endm
.data
;<2. Здесь можно описывать статические переменные.>
Num1 dd 11223344h, 55667788h
Str1 db "ABCDEF", 0
.code
start:
;<3. Здесь можно вводить команды программиста.>
Mov EAX, Num1; 11223344
Mov dl, [Str2 + 3]; J
macrodef EAX, EDX, Num1
.data
;<4. Здесь можно описывать статические переменные.>
Num2 dd 99aabbcch, 0ddeeff00h
Str2 db "GHIJKLM",0
.code
;<5. Здесь можно вводить команды программиста.>
Mov EBX,[Num2 + 4]; DDEEFF00
Mov dl, [Str1 + 4]; E
macrodef Num2, ESI, EAX
; 6. примеры реальных вызовов макросов и процедур
print "Hello, world!"; макрос сообщения
;---------------------------------------
invoke ExitProcess,0; выход в Windows
end start
Содержимое файла coff1.asm.ELST:
; ИЗУЧЕНИЕ РАСШИРЕННОГО ЛИСТИНГА
; <1. Здесь можно описывать макросы.>
macrodef MACRO par1, par2, par3
LOCAL M3
mov par2, par1; обычная команда
; с обычным комментарием
; Скрытый комментарий
M3:
push par3;; обычные
pop par2;; команды
endm
00000000.data
;<2. Здесь можно описывать статические переменные.>
00000000 11223344 Num1 dd 11223344h, 55667788h
00000008 41 42 43 44 45 Str1 db "ABCDEF", 0
46 00
00000000.code
00000000 start:
;<3. Здесь можно вводить команды программиста.>
00000000 A1 00000000 R Mov EAX, Num1; 11223344
00000005 8A 15 0000001A R Mov dl, [Str2 + 3]; J
macrodef EAX, EDX, Num1
1 LOCAL M3
0000000B 8B D0 1 mov EDX, EAX; обычная команда
1; с обычным комментарием
0000000D 1??0019:
0000000D FF 35 00000000 R 1 push Num1
00000013 5A 1 pop EDX
0000000F.data
;<4. Здесь можно описывать статические переменные.>
0000000F 99AABBCC Num2 dd 99aabbcch, 0ddeeff00h
DDEEFF00
00000017 47 48 49 4A 4B Str2 db "GHIJKLM",0
4C 4D 00
00000014.code
;<5. Здесь можно вводить команды программиста.>
00000014 8B 1D 00000013 R Mov EBX,[Num2 + 4]; DDEEFF00
0000001A 8A 15 0000000C R Mov dl, [Str1 + 4]; E
macrodef Num2, ESI, EAX
1 LOCAL M3
00000020 8B 35 0000000F R 1 mov ESI, Num2; обычная команда
1; с обычным комментарием
00000026 1??001A:
00000026 50 1 push EAX
00000027 5E 1 pop ESI
; 6. примеры реальных вызовов макросов и процедур
print "Hello, world!"; макрос сообщения
2 LOCAL nustr
= " 2 quot SUBSTR <"Hello, world!">,1,1
2 IFIDN quot,<">
0000001F 2.data
0000001F 48 65 6C 6C 6F 2??001B db "Hello, world!",0
2C 20 77 6F 72
6C 64 21 00
00000028 2.code
2 EXITM <ADDR??001B>
00000028 68 0000001F R * push OFFSET??001B
0000002D E8 00000000 E * call StdOut
1 invoke StdOut,reparg("Hello, world!")
1 IFNB <>
1 invoke StdOut,chr$()
1 ENDIF
;---------------------------------------
invoke ExitProcess,0; выход в Windows
00000032 6A 00 * push +000000000h
00000034 E8 00000000 E * call ExitProcess
end start
При макрорасширении сделал подстановку тел макросов, замену формальных параметров внутри тела макроса на фактические параметры, а локальные метки макроопределений были заменены на??001A и??0019.
Выводы
Во время лабораторной работы мы изучили технику создания и применения макросов, научились наблюдать за результатами макрогенератора, встроенного в ml.exe.
Остренок ЗКІт-151
КОНСОЛЬНЫЙ ВВОД-ВЫВОД
4.1 Цель работы
Изучить основные возможности ввода-вывода, применяемые в консольных приложениях Windows.
4.2 Выполнение работы
4.2.1 Ввод-вывод функциями Win32
Ниже приведен код программы, после внесения изменений, согласно полученного задания по тестированию функций консольного ввода-вывода из API Win32.
;cio-api.asm
include \masm32\include\masm32rt.inc
comment * ===========================
Шаблон минимальной учебной программы
* ===================================
.data
ZapisanoByte dd 0
AnyString db "Строка для вывода.",0
DlinaStroki dd 18
PotokStdOut dd?
InputBuffer db 25 dup(0)
bLen dd 23
ProchitanoByte dd 0
PotokStdIn dd?
.code
start:
;ТОЧКА А
invoke GetStdHandle, STD_INPUT_HANDLE
mov PotokStdIn, eax
invoke SetConsoleMode, PotokStdIn, \
ENABLE_LINE_INPUT or \
ENABLE_ECHO_INPUT or \
ENABLE_PROCESSED_INPUT
invoke ReadFile, PotokStdIn, ADDR InputBuffer, bLen, ADDR ProchitanoByte, NULL
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov PotokStdOut, eax
invoke WriteFile, PotokStdOut, ADDR InputBuffer, ProchitanoByte, ADDR ZapisanoByte, NULL
inkey
invoke ExitProcess,0
end start
На рисунке 4.1 представлен результат выполнения сценария, представленого выше.
Рисунок 4.1 – Результат выполнения программы cio-api.exe
4.2.2 Испытание макросов консольного ввода и вывода
Ниже приведен листинг программы cio.exe, в которой используются макросы консольного ввода и вывода.
;cio.asm
include \masm32\include\masm32rt.inc
comment * ===========================
Шаблон минимальной учебной программы
* ===================================
.data
lpNumString dd 0
.code
start:
mov lpNumString, input("Введите 16ричное число: ")
print "На самом деле введен текст "
print lpNumString, 13, 10
;ТОЧКА А
inkey "Нажмите пробел..."
invoke ExitProcess,0
end start
На рисунке 4.2 представлен результат выполнения сценария, представленого выше.
Рисунок 4.2 – Результат выполнения программы cio.exe
4.2.3 Преобразование строки в число и обратно
Ниже приведен код программы, после внесения изменений, согласно полученного задания по преобразованию строки в число и числа в строку.
;cio.asm
include \masm32\include\masm32rt.inc
comment * ===========================
Шаблон минимальной учебной программы
* ===================================
.data
lpNumString dd 0
.code
start:
mov lpNumString, input("Введите 16ричное число: ")
print "На самом деле введен текст "
print lpNumString, 13, 10
mov EDX, h2ud(lpNumString)
mov EBX, DWORD PTR [EDX]
print "Обратный вывод введенного числа = ", 13, 10
print str$(EBX), 13, 10
print "То же число, но 16-рично: "
print hex$(EBX), 13, 10
;ТОЧКА А
inkey "Нажмите пробел..."
invoke ExitProcess,0
end start
На рисунке 4.3 представлен результат выполнения сценария, представленого выше.
Рисунок 4.3 – Результат выполнения программы cio.exe
4.2.4 Получения кода символа
В тексте сценария, представленного ниже, предусмотрено получения кода символа выведенного при исполнении макроса inkey.
;cio.asm
include \masm32\include\masm32rt.inc
comment * ===========================
Шаблон минимальной учебной программы
* ===================================
.data
lpNumString dd 0
.code
start:
mov lpNumString, input("Введите 16ричное число: ")
print "На самом деле введен текст "
print lpNumString, 13, 10
mov EDX, h2ud(lpNumString)
mov EBX, DWORD PTR [EDX]
print "Обратный вывод введенного числа = ", 13, 10
print str$(EBX), 13, 10
print "То же число, но 16-рично: "
print hex$(EBX), 13, 10
;ТОЧКА А
inkey "Нажмите пробел..."
print str$(eax), 13, 10
inkey "Выскочил код пробела 32?"
invoke ExitProcess,0
end start
На рисунке 4.4 представлен результат выполнения сценария, представленого выше.
Рисунок 4.4 – Результат выполнения программы cio.exe
ВыВОДЫ
Во время лабораторной работы мы изучили основные возможности ввода-вывода, применяемые в консольных приложениях Windows, а также рассмотрели различные способы преобразования строки в числа и наоборот.
Остренок ЗКІт-151