МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

ЧЕРНИГОВСКИЙ НАЦИОНАЛЬНЫЙ ТЕХНОЛОГИЧЕСКИЙ УНИВЕРСИТЕТ

КАФЕДРА ИНФОРМАЦИОННЫХ И КОМПЬЮТЕРНЫХ СИСТЕМ

СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ

ДЛЯ «ЧАЙНИКОВ»

Методические указания для подготовки к сдаче
нормативной дисциплины «Системное программирование»
по определенным в рабочей программе минимальным требованиям

Для студентов профессионального направления
6.050102 «Компьютерная инженерия»

Обсуждено и рекомендовано

на заседании кафедры

информационных и
компьютерных систем,
протокол №2 от 01.01.2001 г.

Чернигов ЧНТУ 2014

Системне програмування для «чайників». Методичні вказівки для підготовки до здачі нормативної дисципліни «Системне програмування» за визначеними в робочій програмі мінімальними вимогами. Для студентів професійного напряму 6.050102 «Комп’ютерна інженерія»/ Укл. – Чернігів: ЧНТУ, 2014. - 19 с., рос. мовою

Укладач: Нестеренко Сергій Олександрович, кандидат технічних наук, доцент

Відповідальний за випуск: Казимир Володимир Вікторович, завідувач кафедри інформаційних та комп’ютерних систем, доктор технічних наук, професор

Рецензент: Акименко Андрій Миколайович, кандидат фізико-математичних наук, доцент кафедри інформаційних та комп’ютерних систем Чернігівського національного технологічного університету

СОДЕРЖАНИЕ

ВСТУПЛЕНИЕ. 4

МИНИМАЛЬНЫЕ КОМПЕТЕНТНОСТИ ПРИ СДАЧЕ СИСТЕМНОГО ПРОГРАММИРОВАНИЯ. 5

КАК БУДЕТ ПРОИСХОДИТЬ СДАЧА ЗАДОЛЖЕННОСТИ. 6

ПОДРОБНЫЕ ОБЪЯСНЕНИЯ К МИНИМАЛЬНЫМ КОМПЕТЕНТНОСТЯМ.. 7

1... СРЕДА ИСПОЛНЕНИЯ ПРОГРАММ.. 8

НЕ нашли? Не то? Что вы ищете?

2... ПАКЕТНЫЙ ФАЙЛ. 10

3... КОНСОЛЬНЫЙ ВВОД-ВЫВОД. 11

4... МАКРОСЫ.. 13

5... ЦИКЛЫ.. 15

6... БИТЫ.. 17

7... ПРОЦЕДУРЫ.. 20

8... РЕКОМЕНДОВАННАЯ ЛИТЕРАТУРА. 23

ВСТУПЛЕНИЕ

Не все студенты завершают изучение этой дисциплины нормальным образом. Некоторые в итоге оказываются неуспевающими, когда оценки по предмету нет. Подобных неподготовленных студентов в данном издании шуточно назвали «чайниками» и это пособие адресовано именно им. Мы надеемся, вы не в обиде за «чайника»?

Администрация вуза требует от студента ликвидировать эту задолженность, угрожает отчислением. Что делать? Самое правильное – повторно пройти этот курс, выполнить, как положено, все виды учебной работы и в таком «стандартном» режиме получить заслуженную оценку. Он подтверждает тот факт, что студент дисциплину освоил, приобрёл (в терминах ЕКТС) необходимые компетенции.

Но на это у учащихся и их родителей (спонсоров) обычно не хватает ни желания, ни средств, ни времени,. Поэтому руководители высшего образования в Украине придумали более лёгкий (хотя, если честно, и более халтурный) путь – они потребовали от кафедр и преподавателей включить в рабочие программы дисциплин описания т. н. «минимальных требований», выполнив которые, неуспевающий получит право на положительную оценку, тоже, разумеется, минимальную. То есть, по сути, речь идет об «усеченном» варианте освоения дисциплины, который соответствует минимальной положительной оценке (60 баллов ЕКТС). Вопрос о том, насколько такое «освоение» соответствует требованиям рынка труда, тут не обсуждается. Нам приказано – мы делаем.

Рабочей программой этой дисциплины упомянутые минимальные требования определены. Они сводятся к проявлению компетенций по семи темам, которые составляют разделы данных методических указаний. Наличие компетенций проверяется по факту решения простых задач в присутствии преподавателя.

Вместе с тем, практика применения такого способа сдачи дисциплины показывает, что студенты испытывают значительные трудности в подготовке к нему. По разным причинам.

Для помощи им и были написаны настоящие указания. В них содержатся объяснения по преодолению заданий минимального набора, что, по замыслу составителя, поможет успешнее подготовится к ликвидации задолженности.

Из изложенного выше следует, что выполнение студентом этих семи заданий приносит ему только и исключительно минимальную положительную оценку - 60 баллов. Достижение более высоких оценок возможно только при стандартном процессе изучения дисциплины, выполнении всех видов учебной работы по ней и получении зачета в установленный правилами вуза период зачетно-экзаменационной сессии.

Для выполнения заданий минимального цикла вам понадобится компьютер с установленными на нём пакетом MASM32 и текстовым редактором Notepad++.

МИНИМАЛЬНЫЕ КОМПЕТЕНТНОСТИ
ПРИ СДАЧЕ СИСТЕМНОГО ПРОГРАММИРОВАНИЯ

1 СРЕДА ИСПОЛНЕНИЯ ПРОГРАММ

Найти в папках пакета МАСМ32 файлы помощи. Настроить переменную path таким путём, чтобы в консоли ввод текста “masm32.chm” из любой активной папки приводил к открытию этого файла помощи. Открыть в консоли папку C:\users\ваше_usermname и продемонстрировать работоспособность этой настройки на компьютере.

Сделать так, чтобы двойной щелчок по любому файлу с расширением log открывал бы его в редакторе Notepad++. Практически продемонстрировать работу настройки на компьютере.

Средствами Total Commandera получить список всех файлов с расширением chm на диске D: вашего компьютера. Показать на компьютере результат.

2 ПАКЕТНЫЙ ФАЙЛ

Создать на компьютере пакетный файл, в котором нужно сделать следующую работу.

Отключить эхо-выводы. Проверить работоспособность интернета вызовом ipconfig, вывод утилиты дописать в лог-файл. Просмотреть в папке-параметре все *.log-файлы одним вызовом more. (Это означает, что путь к папке передается пакетному файлу как параметр). Организовать паузу для просмотра результатов. Результат показать на компьютере.

3 КОНСОЛЬНЫЙ ВВОД-ВЫВОД

Создать консольную программу, в которой макросами пакета МАСМ32 ввести строку и выполнить ее эхо-вывод.

Организовать программную задержку до нажатия любой клавиши с подсказкой «Нажмите какую-нибудь клавишу для продолжения…». Всё показать на компьютере.

4 МАКРОСЫ

Дан кусочек исходного текста с меткой внутри. Корректно (ручкой на бумаге) преобразовать его в макрос. Написать на бумаге две подстановки этого макроса в программу, показав знание того, как обрабатываются повторные вставки меток.

5 ЦИКЛЫ

Ручкой на бумаге описать sz-строку в секции данных. На бумаге написать цикл, который позволяет определить длину строки. Объяснить написанное.

6 БИТЫ

Написать на бумаге команду, которая установит старший бит регистра AН.

Написать на бумаге команду, которая сбросит младший бит регистра AН.

Написать на бумаге команду, которая инвертирует три старших бита в регистре EAX.

7 ПРОЦЕДУРЫ

Аналогично заданию 1 создать возможность вызова системного пакетника buildc. bat из любой папки компьютера. Показать в Total Commandere, что это работает. Это нужно для дальнейшего выполнения этого задания, потому что написанную вами программу вы будете превращать в ехе-модуль пакетником buildc. bat.

Создать простейшую консольную программу с процедурой сложения двух чисел, передаваемых процедуре как параметры, и которая возвращает сумму через стек. Написать ее прототип и вызов с помощью invoke. Нарисовать стековый кадр этой процедуры. Забрать возвращенную процедурой сумму в регистр eax и макросом print показать результат. Программа должна иметь программную задержку для просмотра результата. Реализовать всё на компьютере, показать результат.

Примечание. Фактические задания при сдаче могут быть незначительно изменены по отношению к данному тексту без принципиального увеличения трудоёмкости и без выхода за приводимый здесь перечень проверяемых вопросов.

КАК БУДЕТ ПРОИСХОДИТЬ СДАЧА ЗАДОЛЖЕННОСТИ

Все, о чем мы будем говорить ниже, относятся к ситуации, когда ваши отношения с университетом зашли уже в ту стадию, когда декан поставил вам требование: «не сдаете задолженность через неделю – отчисляем». Вот тогда вступают в силу «минимальные требования».

Сразу вносим ясность. Если исключение где-то далеко, до крайних сроков еще месяцы или недели, будьте любезны, сдавайте всё по требованиям рабочей программы предмета – все положенные лабы и экзамен (или зачет, что определено).

Сдача предмета по минимальным требованиям – это для студента «последний шанс», когда все правильные средства получить оценку по предмету уже исчерпаны. Сюда входит и ситуация, когда студент пропустил все мыслимые и немыслимые сроки ликвидации задолженности, независимо от причин, которыми это было вызвано.

Было бы ошибкой считать сдачу по минимальным требованиям некоей «лазейкой», более лёгким способом «проскочить» сквозь трудную дисциплину. Дескать, я в семестре учиться не хочу и не буду, а потом приду к преподавателю и сдам лёгким способом. Нет, так не будет. Этот шанс вы сможете использовать только один раз, перед исключением, а не удастся – вы перестанете быть студентом и поймёте, наконец, что этот путь в жизни вы выбирали ошибочно и стоит подумать о том, чем бы вы хотели заниматься в жизни не по принуждению, а от души.

Итак, вам разрешено воспользоваться эти облегченным путём. Как теперь всё то будет происходить?

Прежде всего, настройтесь на то, что за один визит к преподавателю вы всё не сдадите, это невозможно просто организационно – вам надо слишком много делать, а потом сделанное показывать и объяснять. Практика показывает, что за визит сдается примерно одна компетентность, максимум две, если они небольшие, и вы хорошо подготовились. Кроме того, не забывайте, что у преподавателя законное рабочее время на ваше обучение уже в прошедшем семестре истрачено, и все эти ликвидации и пересдачи – это лишняя незапланированная работа, которая, по большому счету, преподавателю не интересна и является попросту обузой. Вам делают исключение, не забывайте об этом. И кроме того, если таких, как вы, скапливается несколько, возникает ситуация нехватки времени на всех. Кто-то успеет отчитаться и сдать, кто-то нет. Кто успеет? Самый подготовленный, который не тратит времени зря, а делает задание уверенно и быстро. Готовьтесь, и это будете вы.

Распечатайте «Минимальные компетентности» (предыдущий раздел), напишите вверху свою фамилию и группу. Носите этот лист с собой на сдачу задолженности, в нем будет отмечаться ваш последовательный прогресс.

Сценарий сдачи одной компетентности следующий.

Читаете текст задания. В присутствии преподавателя полностью выполняете его совершенно самостоятельно. Шпаргалками и подсказками пользоваться при сдаче нельзя, если «спалитесь», весь перечень минимальных компетенций начинаете сдавать с самого начала, и те, что уже сданы ранее. Там, где требуется, делаете предписанную часть на компьютере, показываете результат. Наличие компьютера для демонстрации – предмет вашей заботы, не преподавателя. После всего этого отвечаете на все вопросы, приводимые в соответствующем разделе объяснений по компетентностям. В листочке прогресса делается отметка о сдаче. Всё. Переход к следующему заданию.

Задание, не законченное по любым причинам на текущей встрече, в следующий раз повторно сдается с самого начала.

ПОДРОБНЫЕ ОБЪЯСНЕНИЯ
К МИНИМАЛЬНЫМ КОМПЕТЕНТНОСТЯМ

2  СРЕДА ИСПОЛНЕНИЯ ПРОГРАММ

Найти в папках пакета МАСМ32 файлы помощи.

Это нужно для определения пути к папке, в которой находяться файлы помощи. Файлы помощи в операционной системе (ОС) Windows – это чаще всего файлы типа chm (Compiled Help Modules). По своему внутреннему устройству они подобны интернетовским html-файлам, но не с текстовыми, а числовыми тегами разметки. Кроме того, они обычно сжаты.

Перейдите Проводником в пакет МАСМ, откройте папку help. Запомните полный путь к этой папке.

Настроить переменную path таким путём, чтобы в консоли ввод текста “masm32.chm” из любой активной папки приводил к открытию этого файла помощи.

Открытие (или любое иное использование) требуемого файла из любой папки файловой системы возможно тогда, когда операционная система гарантированно «заглянет» в папку с этим файлом. Это можно обеспечить, если дописать путь к требуемой папке в строковую системную переменную path (название переводится как «путь»).

Щелкните по кнопке Пуск – Компьютер – (правая мышь) Свойства - Дополнительные параметры системы – Переменные среды – Список «Системные переменные», выбрать Path – Изменить… - Курсор на конец строки, дописать «;d:\masm32\help;» - ОК – ОК – ОК.

Чтобы ОС «взяла» измененное значение path, компьютер надо перезагрузить, потому что все системные переменные читаются при старте ОС.

Откройте консоль Win-R – cmd, введите в командной строке “masm32.chm”, хелп-файл откроется. Обратите внимание на то, какая папка в данный момент активна.

Сделать так, чтобы двойной щелчок по любому файлу с расширением log открывал бы его в редакторе Notepad++.

Это означает, что по умолчанию щелчок по файлу с расширением log должен открывать его в редакторе Notepad++. На грамотном языке это называется «назначить обработчиком файлов типа log текстовый редактор Notepad++». В принципе, это совершенно законное действие для любых неформатированных текстовых файлов. Поскольку лог-файлы – это обычно текстовые дневники записей про выполнение разнообразных действий, то открывать их можно любым текстовым редактором, Notepad++ в том числе

Создайте средствами Windows текстовый документ с любым именем. Переименуйте его в расширение log. Щелкните правой кнопкой по этому файлу – Открыть с помощью… - Обзор… - Выбрать C:\Program Files (x86)\Notepad++\notepad++.exe – Открыть – þ Использовать эту программу для всех файлов этого типа – OK.

Проверка: Щелкните дважды по лог-файлу. Должен открыться в Notepad++.

Средствами Total Commandera получить список всех файлов с расширением chm на диске D: вашего компьютера.

Открыть Total Commander. Выполнить Команды – Поиск файлов – Искать файлы ввести chm – Место поиска ввести D:\ – Начать поиск.

Список найденных папок и файлов, в названиях которых присутствует подстрока «chm», будет показан в окне «Результаты поиска». Перейти к любому найденному файлу можно двойным щелчком по нему.

2.1  Вопросы для самопроверки

а)   Для чего операционной системе нужна строка path?

б)   Как запустить консоль?

в)   Что такое «обработчик по умолчанию»?

г)   Как найти нужный файл на диске с помощью Total Commander?

3  ПАКЕТНЫЙ ФАЙЛ

Создать на компьютере пакетный файл, в котором нужно сделать следующую работу.

Создать текстовый документ, предположим, paket. txt, сменить расширение файла с txt на bat.

Отключить эхо-выводы.

Команда echo off в пакетном файле отключает эхо-вывод для всех команд, расположенных после неё. Чтобы не было эхо-вывода у самой этой команды, нужно перед ней поставить символ «эт» Окончательно получится @echo off.

Проверить работоспособность интернета вызовом ipconfig,…

ipconfif /all

…вывод этой утилиты дописать в лог-файл.

Дописать после ipconfig /all перенаправление потока вывода в лог-файл с дописыванием в его конец

Ipconfig /all >> d:\internet.log

Здесь >> - это команда «дописать в конец файла». Команда > будет писать вывод в файл, который будет каждый раз создаваться заново.

Просмотреть в папке-параметре все *.log-файлы одним вызовом more. (Это означает, что путь к папке передается пакетному файлу как параметр).

more %1\*.log

Предположим, вызов пакетного файла имеет вид

Paket d:\mylog

Тогда внутрь пакета на место %1 будет подставлен 1-й параметр командной строки, то есть строка «d:\mylog». %1 – это символическое имя первого параметра командной строки. Значит, строка просмотра всех лог-файлов перед исполнением примет вид more d:\mylog\*.log. Присутствие символического имени позволяет задавать для просмотра любую нужную папку, что расширяет возможности пакетного файла.

Организовать паузу для просмотра результатов.

pause

3.1  Вопросы для самопроверки

а)   Для чего предназначены пакетные файлы?

б) Как создаются пакетные файлы?

в) Как передавать параметры внутрь пакетных файлов?

г)   Как перенаправить поток вывода в файл? Как дописать вывод в конец файла?

д) Как организуется пауза при выполнении пакетного файла? Зачем это нужно?

4  КОНСОЛЬНЫЙ ВВОД-ВЫВОД

Создать консольную программу, …

Используйте стандартный шаблон исходного текста ассемблерной программы

include \masm32\include\masm32rt. inc

comment * ===========================

Шаблон минимальной учебной программы

* ===================================

.data

; Описание числовых и строковых переменных

.code

start:

;ТОЧКА А. Команды ассемблера и вызовы макросов

invoke ExitProcess,0 ; выход в Windows

end start

Include-файл masm32\include\masm32rt.inc содержит инструкции подключения к программе всех прототипов и библиотек пакета MASM32. Откройте этот файл в Notepad++ и просмотрите хотя бы его начало. Для нормальной работы с этим шаблоном должны быть прописаны в path пути d:\masm32\; d:\masm32\bin; d:\masm32\inc; d:\masm32\lib, потому что подключаемые файлы находятся именно в этих папках. Если этих путей в path не будет, нормальной сборки программы не произойдет и она не откомпилируется.

Исполняемый ехе-модуль создается вызовом buildc имя_исходного_файла. Расширение asm тут писать не следует.

в которой макросами пакета МАСМ32 ввести строку…

Следует использовать макрос input("Подсказка для ввода:"). Этот макрос принимает с клавиатуры ввод строки в автоматически создаваемую строковую переменную и возвращает адрес этой строковой переменной. Этот макрос – функционально вызываемый, то есть он используется как операнд выражения. Например такого:

mov EDX, input("Введите строку:")

Здесь регистр EDX назначен как ячейка, куда будет записан адрес строки, автоматически созданной макросом inkey(). Можно было бы использовать имя 4-хбайтной переменной, но тогда ее следовало бы сначала создать в секции данных (Точка Д шаблона), например, так:

Var4 dd 0

… и выполнить ее эхо-вывод.

Макрос print позволяет вывести на экран консоли строку, задаваемую адресом. Поскольку предыдущая команда адрес строки сохранила в EDX, то его и следует использовать в print. После строки неплохо бы вставить перевод строки в виде вывода двух управляющих курсором байтов 13, 10. Окончательно

print edx, 13, 10

Организовать программную задержку до нажатия любой клавиши с подсказкой «Нажмите какую-нибудь клавишу для продолжения…».

inkey «Нажмите какую-нибудь клавишу для продолжения…».

4.1  Вопросы для самопроверки

а)   Что записано в файле masm32\include\masm32rt. inc? Какой смысл в этих записях?

б) Почему для использования этого шаблона нужен гарантированный доступ к папкам bin, lib, include пакета MASM32?

в) Как ввести в программу текстовую строку?

г)   Как текстовую строку вывести на экран консоли?

д) Как при выводе курсор консоли перевести на новую строку?

е)   Как организовать программную задержку выполнения для просмотра результатов?

5  МАКРОСЫ

Дан кусочек исходного текста с меткой внутри.

Кусочек может быть абсолютно любой. Например, такой:

mov ax, bx

push eax

m1:

pop edx

jne m1

Корректно (ручкой на бумаге) преобразовать его в макрос.

Преобразование фрагмента исходного текста выполняется дописыванием сверху заголовка макроса с ключевым словом MACRO, а снизу – завершителя ENDM. Заголовок может быть, например такой: MyFrag MACRO.

Но «корректно» сздать макрос означает еще и не забыть про внутренние метки. Здесь это метка m1.

Проблема с этими метками состоит вот в чём. Макросы обычно многократно подставляются в программу, они и существуют-то для того, чтобы освободить программиста от повторного написания одинаковых кусков исходного текста. При вызове макроса строчка его вызова заменяется в исходном тексте программы телом макроса, то есть приведенным выше «кусочком». Но сколько раз мы вызовем макрос MyFrag, столько раз и попадет в исходный текст метка m1. Этого допускать нельзя, потому что метка – это адресная константа, численно равная смещению метки в секции кода. Может константа иметь больше одного значения? – Очевидно, что нет. (Простая аналогия. Может на одной улице быть несколько домов с одинаковым номером 14? Как почтальон разберется, в какой из них доставлять письма? Неправильная ситуация, недопустимая). Как же обеспечить уникальность внутренних меток при повторных вставках тела макроса в программу?

Эту работу для нас легко сделает макрогенератор, встроенный в компилятор ML. EXE. Достаточно после заголовка макроса написать LOCAL, и перечислить метки макроса, которые должны обыть в программе уникальными. В нашем случае это LOCAL m1. Окончательно текст макроса получается такой:

MyFrag MACRO

LOCAL m1

mov ax, bx

push eax

m1:

pop edx

jne m1

ENDM

Написать на бумаге две подстановки этого макроса в программу, показав знание того, как обрабатываются повторные вставки меток.

Для описанных локальних меток макрогенератор при подстановках автоматически генерирует искусственные имена по шаблону??XXXX, где ХХХХ – это запись последовательных чисел в 16-ричном формате от 0000 до FFFF. Имена в ассемблере должны начинаться с буквы, но символы?, _, @ в ассемблере считаются буквами, так что всё в порядке.

При первой подстановке метку «окрестят» ??0000, при второй - ??0001 и так далее.

Раз так, первая подстановка нашего макроса выглядит так:

mov ax, bx

push eax

??0000:

pop edx

jne??0000

Вторая:

mov ax, bx

push eax

??0001:

pop edx

jne??0001

Как видим, в каждой подстановке имя метки разное, что и требовалось.

5.1  Вопросы для самопроверки

а)   Какой цели служит использование макроса?

б) Что такое «локальная метка в макросе»?

в) Как макрогенератор обеспечивает уникальность локальных меток при повторных вставках макроса?

г)   Является ли символ «?» буквой в ассемблере?

6  ЦИКЛЫ

Ручкой на бумаге описать sz-строку в секции данных.

Любая строка – это массив кодов символов, то есть однобайтных целых чисел. Код символа соответствует изображению выводимого символа. Коды и изображения символов связываются через т. н. кодовые таблицы. Например, код 65 соответствует изображению заглавной английской А.

Чтобы обозначить в памяти конец строки, принято за последней литерой строки ставить байт со значением 0 (ноль-байт). Строки с таким «довеском» называются sz-строками, или ASCIIZ-строками. Расшифровка аббревиатур: «sz» от «String and Zero», «ASCIIZ» от «American Standard Code of Information Interchange with Zero».

Описание строки в секции данных обычное: метка (то есть имя), директива размещения db, перечисление символов строкой и/или числами. Например:

FileName db “Введите имя файла:”, 13, 10, 0

Раз последний байт этой строки ноль, то это – sz-строка.

На бумаге написать цикл, который позволяет определить длину строки.

Чтобы заставить процессор бесконечно повторять какую-то последовательность команд, можно организовать безусловный (без проверки любых условий) возврат к ее началу:

Povtor:

Команда1

Команда2

Команда3

КомандаN

JMP Povtor

Здесь Povtor – метка возврата, JMP Povtor – команда безусловного перехода на метку Povtor.

Разумеется, если процессор начнет выполнять такой цикл, то сам собой он не прекратится никогда, внешне это будет выглядеть как «зависание» программы. Поэтому такие циклы реально не применяются. Надо вставить в цикл команды выхода по какому-нибудь условию, тогда применять можно.

Как «посетить» каждый символ строки? С помощью «бегущего указателя». Им может быть любой регистр общего назначения (eax, ebx, ecx, edx, esi, edi). Например, возьмем ecx. До входа в цикл присвоим ему адрес начала строки, то есть ее первого символа:

Mov ecx, offset Filename

Здесь offset – директива взятия адреса метки.

Будем в каждом повторе тела цикла увеличивать есх на 1, чтобы он «сдвигался» на очередной символ. Это команда инкремента inc ecx. Но эту «сдвижку» надо прекратить, когда регистр-указатель есх укажет на ноль-байт, это конец строки. Чтобы узнать, попали ли мы на ноль-байт, надо сначала выполнить сравнение

Cmp byte ptr [ecx], 0

Здесь [ecx] – это байт, на который указывает есх (скобки [] означают разадресацию). Слова byte ptr приказывают процессору считать число в есх указателем на одиночный байт (а не, предположим, слово или двойное слово).

Если это сравнение (а оно по сути есть вычитание) покажет равенство этих величин, то команда JE метка_выхода отреагирует на факт выполнения этого условия и «выбросит» исполнение на метку_выхода, котрую надо разместить где-нибудь за пределами цикла.

Ну, и что у нас получается на данный момент, если всю эту премудрость свести вместе? А вот что.

mov ecx, offset Filename

povtor:

Cmp byte ptr [ecx], 0

JE metka_vyhoda

Inc ecx

JMP povtor

metka_vyhoda:

Чтобы сосчитать число повторов этого цикла (а это и есть количество символов в строке, то есть ее длина), нужно использовать какой-нибудь счётчик, ну, к примеру, регистр edx. До входа в цикл его надо обнулить, а перед каждым переходом на следующий символ его надо увеличивать на 1. На выходе из цикла этот счетчик и будет содержать длину строки.

mov edx, 0 ; сброс счетчика

mov ecx, offset Filename

povtor:

Cmp byte ptr [ecx], 0

JE metka_vyhoda

Inc ecx; на след символ

Inc edx ; счетчику +1

JMP povtor

metka_vyhoda:

; тут в edx – длина строки

Примечание. Приведенный здесь алгоритм – самый примитивный и понятный. Есть много алгоритмов, которые более совершенны, но их и сложнее разбирать, здесь это не является нашей задачей.

6.1  Вопросы для самопроверки

а)   Как организовать бесконечный цикл?

б)   Как производиться проверка на ноль-байт в строках?

в)   Чем отличается работа команды безусловного перехода JMP от команды «перехода по равенству» JE?

г)   Как установить указатель на начало строки?

д)   Как синтаксически показывается операция разадресации указателя?

7  БИТЫ

7.1  Терминология

«Установить» бит – это значит, что после этого действия бит имеет значение 1, какое бы значение он ни имел до операции, хоть 0, хоть 1.

«Сбросить» бит – это значит, что после этого действия бит имеет значение 0, какое бы значение он ни имел до операции, хоть 0, хоть 1.

«Инвертировать» бит – это значит, что после этого действия бит имеет значение, обратное тому, что он имел до операции. Был 0, стал 1. Был 1, стал 0.

7.2  Имена частей регистров общего назначения

Регистры eax, ebx, ecx и edx имеют отдельные имена для своих частей:

Обратите внимание, что старшие половинки регистров (биты 16-31) никаких отдельных имен не имеют. Также нет отдельных имен у однобайтовых половин регистров bp, sp, si, di.

Из схемы также следует, что старший бит в АН имеет смещение 15, а его младший бит имеет смещение 7.

7.2.1  Логические команды

В ассемблере есть логические команды AND, OR, XOR, NOT. Еще есть команда TEST, которая выполняется как AND, но с особенностями, о которых речь ниже.

В ассемблере эти команды обрабатывают пары битов и порождают как результат тоже бит. Биты трактуются: 0 – неправда, ложь; 1 – правда, истина.

Ассемблерный нюанс состоит в том, что один бит как операнд логической команде сообщить никак не возможно, синтаксис допускает операнды размерами, стандартными для процессора: байт, слово (word), двойное слово (dword). В этом случае логические команды AND, TEST, OR, XOR имеют всегда два операнда одинаковой разрядности (byte-byte, word-word, dword-dword). Второй операнд логической команды называют маской.

Биты этих операндов обрабатываются попарно (нулевой с нулевым, первый с первым, второй со вторым и т. д. до последней пары в разрядной сетке.).

Правила вычисления бита-результата («таблицы истинности») такие:

Первый бит

0

0

1

1

Второй бит (маска)

0

1

0

1

Результат AND (и TEST)

0

0

0

1

Результат OR

0

1

1

1

Результат XOR

0

1

1

0

Из битов-результатов составляется значение-результат, и по этому результату устанавливаются флаги. Это делает возможность «отловить» нулевое значение, отрицательное, короче, любое, которое детектируется флагами. И последнее действие при выполнении – команды AND, OR, XOR записывают значение в свой первый операнд; а TEST это значение никуда не пишет, у этой команды (по алгоритму это та же AND) дело заканчивается установкой флагов.

Особняком стоит команда NOT, у неё всегда один операнд (byte, word, dword). И работа этой команды проста – она просто меняет каждый бит своего операнда на противоположный и это значение опять пишет в этот свой единственный операнд.

Поскольку первый операнд перезаписывается, то он не может быть константой.

Проблема 1. Как сбросить бит.

Решение такое:

ГарантированныйНоль = ПроизвольныйБит AND 0;

Итак, правило сброса словесно выражается так: чтобы сбросить бит, надо выполнить для него AND с маской ноль.

Проблема 2. Как установить бит.

Решение:

ГарантированнаяЕдиница = ПроизвольныйБит OR 1;

Итак, правило установки бита словесно выражается так: чтобы установить бит, надо выполнить для него OR с маской 1.

Проблема 3. Как инвертировать бит.

Решение:

ИнвертированныйБит = ИсходныйБит XOR 1;

Написать на бумаге команду, которая установит старший бит регистра AН.

OR ah, 10000000B

Здесь В означает запись число в битовом формате.

Написать на бумаге команду, которая сбросит средние 4 бита регистра AL.

AND AL, 00111100B

Написать на бумаге команду, которая инвертирует три старших бита в регистре EAX.

XOR EAX, 0E0000000h

Здесь старшая тетрада Е (побитовое 1110) в маске обеспечивает инверсию именно трёх старших разрядов ЕАХ.

7.3  Вопросы для самопроверки

а)   Дать определения понятиям «сброс», «установка» и «инвертирование» битов.

б)   Что такое «таблица истинности» логических команд в ассемблере?

в)   Как технически выполнить сброс, установку и инверсию отдельных битов?

г)   Какое смещение имеет младший бит старшей части в ESI?

д)   Чему будет рамен EAX после XOR EAX, EAX?

8  ПРОЦЕДУРЫ

Создать простейшую консольную программу с процедурой сложения двух чисел, передаваемых процедуре как параметры, и которая возвращает сумму через стек.

Сначала о сложении.

Оно выполняется командой add операнд1, операнд2. Эта команда складывает операнд1 с операндом2 и записывает результат в операнд1:

Операнд1 = операнд1 + операнд2.

Операндами могут быть регистры, переменные и константы. Из этой логики вытекают ограничения: 1) операнды не могут одновременно находиться в памяти, т. к. компьютер может в каждый момент времени читать из памяти только одно число; 2)т. к. первый операнд перезаписывается, он не может быть константой. Значит, если нам в памяти даны переменные A и В, то сложить их придется так:

mov EAX, A

add EAX, B ; регистр и переменную складывать можно

И, если нам нужно скопировать сумму (она сейчас в ЕАХ) в переменную R, то нужна еще одна команда:

mov R, EAX

Создать процедуру с двумя параметрами и возвращаемым значением.

Пусть наша процедура будет иметь имя Sum2, а ее параметрами будут двойные слова A и B, а возвращаемым значением – двойное слово R. Тогда текст процедуры такой:

Sum2 PROC A:dword, B:dword, R:dword

; команды процедуры

mov EAX, A

add EAX, B

mov R, EAX

ret

Sum2 ENDP

Написать ее прототип и вызов с помощью invoke.

Sum2 PROTO :dword, :dword, :dword

Прототип нужен макросу invoke для 1) контроля правильности передачи параметров по количеству и типам; 2) для создания группы машинных команд push и call, которые, фактически, и реализуют вызов.

Предположим, мы хотим сложить числа 22 и 2014. Вызов нашей процедуры для этого случая:

invoke Sum2, 22, 2014, 0

Макрогенератор превратит эту строку в четыре машинных команды

Push 0

Push 2014

Push 22

Call Sum2

которые будут откомпилированы в машинный код и, фактически, реализуют вызов процедуры с параметрами.

Нарисовать стековый кадр этой процедуры.

Исходный ESP

R

4 байта

B

4 байта

A

4 байта

Ip возврата

4 байта

Старое EBP

4 байта

АДРЕСА

Забрать возвращенную процедурой сумму в регистр eax…

После выполнения процедуры возвращенное значение находится в ячейке стека R, а указатель стека ESP наодится в «исходном» положении. Значит, копирование в EAX выглядит так:

mov eax, dword ptr [esp – 4]

Словами это можно сказать так: скопировать в ЕАХ двойное слово, находящееся по адресу, на 4 меньшему, чем тот, что сейчас содержится в ESP.

…и макросом print показать результат.

print str$(eax) ,13,10

Здесь str$() – это макрос преобразования числа в строку; 13 и 10 – перевод строки при выводе на консоль.

Программа должна иметь программную задержку для просмотра результата

inkey “Нажмите любую клавишу.”

Собрать это всё в единую программу.

Берем шаблон учебной программы и вставляем в него подготовленные выше кусочки (показаны красным).

include \masm32\include\masm32rt. inc

comment * ===========================

Шаблон минимальной учебной программы

* ===================================

Sum2 PROTO :dword, :dword, :dword

.data

; Описание числовых и строковых переменных

.code

start:

;ТОЧКА А. Команды ассемблера и вызовы макросов

invoke Sum2, 22, 2014, 0

print str$(eax) ,13,10

inkey “Нажмите любую клавишу.”

invoke ExitProcess,0 ; выход в Windows

Sum2 PROC A:dword, B:dword, R:dword

; команды процедуры

mov EAX, A

add EAX, B

mov R, EAX

ret

Sum2 ENDP

end start

Сохранить исходный текст в файл min7.asm. Откомпилировать buildc min7. Выполнить min7.exe, показать преподавателю.

8.1  Вопросы для самопроверки

а)   Как выполняется команда сложения ADD? Какие ограничения существуют на ее операнды?

б)   Как технически сложить две переменных, которые обе находятся в памяти?

в)   Что такое прототип процедуры? По каким правилам он пишется?

г)   Кому нужен прототип и как он используется?

д)   Во что макрогенератор превратит строчку вызова процедуры макросом invoke?

е) В каких местах исходного текста программы следует размещать описания процедур?

9  РЕКОМЕНДОВАННАЯ ЛИТЕРАТУРА

1. Рихтер Дж. WINDOWS для профессионалов: Создание эффективных Win-32 приложений с учетом специфики 64-разрядной версии Windows / Пер. с англ. — 4-е изд. — СПб.: Питер; М.:Издательство «Русская редакция»; 2008 — 720 с., ил.

2.  : Защищенный режим процессоров Intel 286 / 80386 / 80486 .— М.: Диалог-МИФИ, 1993.— 234 с.

3.  Win32. Основы программирования.— М.: Диалог-МИФИ, 1999.— 342 с.