АЛМАТИНСКИЙ ИНСТИТУТ ЭНЕРГЕТИКИ И СВЯЗИ

 

Кафедра Электроники и компьютерных технологий

 

ОСНОВЫ ПРОГРАММИРОВАНИЯ НА ЯЗЫКЕ АССЕМБЛЕРА

 

Методические указания к выполнению лабораторных работ

 

(для студентов всех форм обучения специальности

050704 – Вычислительная техника и программное обеспечение)

 

Алматы 2007

 

          СОСТАВИТЕЛИ: Б.М.Мустафина, А.Т.Конуспаева. Основы программирования на языке Ассемблера. Методические указания к выполнению лабораторных работ для студентов всех форм обучения специальности 050704 – Вычислительная техника и программное обеспечение. – Алматы: АИЭС, 2007. – 39с.

 

 

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

         Методические указания предназначены для студентов вузов, изучающих практические вопросы программирования и специальностей: 3501 – Электронные системы и технологии, 3703 – Организация и технология защиты информации, 3704 – Программное и аппаратное обеспечение вычислительной техники и сетей.

         Ил. 1, табл. 2, библиогр.- 8 назв.

 

         Рецензент: канд.техн.наук, доц. М.А. Ахметова.

Печатается по дополнительному плану издания некоммерческого акционерного общества “Алматинский институт энергетики и связи”             на 2007 г.

© НАО Алматинский институт энергетики и связи”, 2007.


Введение

Язык Ассемблера является машинно-ориентированным языком, т.е. языком процессора. Язык Ассемблера – это универсальный язык структурного программирования, являющийся удобным и гибким средством оптимизации кода программ, написания драйверов,  трансляторов, защитных процедур, программирования некоторых внешних устройств и т.д.

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

Выполнение каждой лабораторной работы должно завершаться оформлением отчета. Отчет о проделанной работе должен содержать:

- цель и задание работы;

- краткие итоги теоретической подготовки;

- результаты проделанной работы (тексты программ, результаты работы программ);

- список использованной литературы.

Выполненная работа и оформленный отчет защищается у преподавателя.

 

1 Лабораторная работа. Ассемблирование и выполнение программ на языке АССЕМБЛЕРА

 

Цель работы: изучить процессы ассемблирования, компоновки и выполнения программы, а также  научиться решать, тестировать и отлаживать на ЭВМ простейшие типовые задачи  как вычислительного, так и не вычислительного характера. Как правило, в самой постановке такой задачи уже определен алгоритм ее решения. Необходимо записать этот алгоритм, используя основные конструкции языка ассемблера. Для проверки правильности работы программы должны быть представлены необходимые тестовые данные.

Задания.

Написать программу.

1 Вывод сообщения на экран с начала строки.

2 Вывод сообщения на экран с середины экрана.

3 Вывод сообщения на экран с начала строки и в рамке, построенной из любых символов псевдографики.

4 Вывод сообщения в рамке на середину экрана.

5 Вывод на экран символа с помощью функции 2h, для этого запишите в сегменте кодов:

 

mov

ah, 2h

; функция вывода символа на экран

 

mov

dl, ‘A’

;ASCII

 

int

21h

;прерывание DOS

6 Вывод сообщения на экран. Перед выдачей сообщения очистить экран функцией 6 int 10h:

 

mov

ah, 6h

; функция очистки экрана

 

mov

al, 0

; 0 - весь экран

 

mov

ch, 0

; номер строки левого верхнего угла (0-24)

 

mov

cl, 0

; номер столбца левого верхнего угла (0-79)

 

mov

dh, 24

; номер строки правого нижнего угла (0-24)

 

mov

dl, 79

; номер столбца правого нижнего угла (0-79)

 

mov

bh, 30h

; байт атрибут (на бирюзовом фоне черные символы)

 

int

10h

; прерывание BIOS (видеосервис)

Вставить эти 8 команд после 9-й строки.

7 Вывод сообщения на экран. Перед выдачей сообщения установить курсор функцией 2 int 10h:

 

mov

ah, 2h

; функция установки курсора

 

mov

bh, 0

; текущая видеостраница

 

mov

dh, 5

; номер строки –5

 

mov

dl, 10

; номер столбца -10

 

int

10h

; прерывание BIOS (видеосервис)

Вставить эти команды перед выдачей символа или сообщения.

8 Вывод сообщения на экран. Перед выдачей сообщения нарисовать цветное окно функцией 6 int 10h и установить курсор функцией 2 int 10h.

 

           Методические рекомендации по выполнению лабораторной работы

При описании переменных в сегменте данных данные можно описывать с помощью псевдооператоров (директив) DB, DW, DD.

Например:

A       DB        1, 2, 3, 4

B        DW       1122h,344h

C        DD       11223344h, 55667788h

Если требуется работа с байтами, то обращение к ним осуществляется с помощью оператора byte ptr:

mov   AL, A                            ; AL = 1

mov   AL, byte ptr B                ; AL = 22h

mov   AL, byte ptr C                ; AL = 44h

Во втором и третьих примерах в регистр AL будут записаны младшие байты слов и двойных слов.

Для обращения к старшим байтам нужно к адресу добавить необходимое смещение:

mov   AL, byte ptr B+1  ; AL = 11

mov   AL, byte ptr C+3  ; AL = 11

Если требуется работа со словами, то обращение к ним осуществляется с помощью оператора word ptr:

mov   AX, word ptr A    ; AX = 0201h

mov   AX, B                   ; AX = 1122h

mov   AX, word ptr C    ; AX = 3344h

При обращении к старшим словам нужно к адресу добавить смещение для слов (кратное 2):

mov   AX, word ptr C+2 ; AX = 1122h

В программах могут использоваться константы, которые описываются с помощью псевдооператоров EQU или " = "

; в сегменте данных

К         EQU     255

A         DB       ?

; в сегменте кода

mov   A, K

В данном случае второй операнд является непосредственным, а первый операнд указывает адрес.

Массивы можно задавать следующим образом:

mas_A      DB       1, 2, 3, 4, 5, 6, 7, 8, 9

mas_B        DB    31h, 32h, ..., 39h

mas_C        DB    '1, 2, 3, 4, 5, 6, 7, 8, 9' ;   данный массив занимает в

;памяти 17 байтов,  т.к. включает в себя разделители (запятые)

mas_D         DB    1B, 10B, 11B, 100B, 101B, 110B, 111B, 1000B   ;Массив

;задан в двоичном коде

Массивы, заданные в двоичном и десятичном виде, перед выдачей на экран необходимо преобразовать в ASCII-коды.

mov   AL, 2

mov   DL, mas[SI]

add    DL, 30h                ; получение ASCII - кода

int      21h

Текстовые строки задаются в ASCII-кодах, т.е. обязательно заключаются в кавычки.

string_A     DB    'При использовании функции 9'

                             DB    'INT 21h текстовая строка', 10, 13

                             DB    'Должна заканчиваться символом '

                             DB    'доллара $'

string_B     DB    'При использовании функции 40h'

                             DB    'INT 21h конец  текстовой строки', 10, 13

                             DB    'Определяется по счетчику $ '

При выводе рамки на дисплей ее можно описать в сегменте данных в виде текстовой строки:

RAMKA     DB    10,13,          10 DUP (20h), '                    ' , 10, 13

DB              10 DUP (20h), '                    ' , 10, 13

DB              10 DUP (20h), '                    ', 10, 13

DB              10 DUP (20h), '                    $'

или

         RAMKA     DB    10, 13, 10 DUP (20h), 218, 8 DUP (196), 191

DB    10, 13, 10 DUP (20h), 179, 8 DUP (20h), 179

DB    10, 13, 10 DUP (20h), 179, 8 DUP (20h), 179

DB    10, 13, 10 DUP (20h), 192, 8 DUP (196), 217, '$'

ASCII - коды псевдографики для рисования рамок:

 

218

 

 

196

 

191

 

 

 

 

 

 

 

 

 

 

179

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

192

 

 

 

 

217

 

При выводе символа на дисплей в регистр DL (функция 2 INT 21h) загружается ASCII-код символа:

mov   DL, 41h       ; ASCII-код символа 'A'

или

mov   DL, 'A'

При составлении программы на языке ассемблера можно выделить следующие этапы:

         а) составление блок – схемы;

         б) создание исходной программы NAME.ASM, где NAME – любое допустимое в MS DOS  имя файла;

         в) создание объектной программы NAME.OBJ;

          г) создание исполняемой программы NAME.EXE;

          д) выполнение EXE – программы;

          е) проверка результатов.

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

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

Транслятор (компилятор) формирует дисковый файл, содержащий объектный модуль NAME.OBJ (текст программы на машинном языке, но без реализации связей между подпрограммами).

Компоновщик (загрузчик) осуществляет компоновку результирующих модулей с предполагаемыми библиотечными модулями и завершает определение адресных ссылок, т.е. создает перемещаемый исполняемый модуль NAME.EXE. Представленный здесь Турбо Ассемблер, включающий встроенные компилятор, компоновщик и отладчик, разработан фирмой Borland International для семейства микрокомпьютеров IBM PC. Он совместим с ассемблером MASM фирмы Microsoft Corporation, но, кроме того,  содержит много полезных расширений и улучшений и обладает более высоким быстродействием.

Компилятор Турбо Ассемблера – это выполняемая программа, размещенная в файле TASM. EXE. Компилятор вызывается командой

Tasm Name.asm,

в которой Name.asm является именем компилируемого файла и создает перемещаемый объектный файл Name.obj.

Вызов компилятора в общем случае имеет вид:

TASM fileset; fileset; …; fileset

где fileset представляет собой конструкцию вида

options, sources, object, list, xref

причем options представляет собой название  опции, sources – имя исходного файла или последовательность таких имен, разделенных символом + (плюс) либо пробелом, object – имя результирующего файла(.OBJ), list - имя файла, куда будет помещен листинг компиляции, а xref – имя файла, куда будет помещена таблица перекрестных ссылок. Таблица перекрестных ссылок содержит перечень символических имен модуля, мест, в которых они определены, а также номера строк, в которых появились ссылки на них.

Например, команда

TASM  /l  prim1+prim2, prim; /zi test

приведет к созданию из исходных модулей prim1.asm и prim2.asm результирующего модуля prim.obj , а также  листинга компиляции, который будет помещен в файле prim.lst (опция /l) и, кроме того, созданию из исходного модуля test.asm с использованием опции /zi результирующего модуля test.obj.

С целью создания исполнительной программы необходимо провести компоновку результирующих модулей .obj с предполагаемыми библиотечными модулями. Эту задачу выполняет компоновщик Turbo Link фирмы Borland Int.

Компоновщик является выполняемой программой, хранящейся в файле TLINK.EXE.

Вызов компоновщика TLINK в общем случае имеет вид

TLINK options, objects, exec, map, libraries

где options – набор опций, objects – множество имен файлов, содержащих результирующие модули, exec – имя файла, в который будет помещена выполняемая программа, map – имя файла, в который будет помещена карта компоновки, libraries – множество имен файлов, содержащих библиотеки результирующих модулей. Опции отделяются пробелами, имена файлов должны быть отделены пробелами или знаками + (плюс).

 

Порядок выполнения работы.

1 Введите в компьютер исходный ассемблерный текст программы с помощью любого текстового редактора. При использовании встроенного редактора NC:

F4 – редактирование выделенного курсором файла;

SHIFT+F4 – создание нового файла, не имеющегося на диске, нужно ввести имя файла;

ALT+F4 – внешний редактор.

Введите данную программу:

(Номера строк и угловые скобки не набирать!)

Data

segment

 

<1 >

string

db

db

‘Ваши фамилия и имя :……. ‘ ,13,10

’Ваш возраст : …..’,’$’

< 2>

<3 >

data

ends

 

< 4>

code

segment

 

< 5>

 

assume

cs:code, ds:data

< 6>

start:

 

 

< 7>

 

mov

ax, data

< 8>

 

mov

ds, ax

< 9>

 

mov

dx, offset string

< 10>

 

mov

ah,9h

< 11>

 

int

21h

< 12>

 

mov

al,0

< 13>

 

mov

ah,4ch

< 14>

 

int

21h

< 15>

сode

ends

 

< 16>

 

end

start

< 17>

2 После выхода из редактирования убедитесь в наличии вашей программы в текущем каталоге – Name.ASM. Для получения .OBJ – модуля, необходимо в командную строку набрать имя транслятора и имя вашего файла:

TASM.EXE          NAME.ASM

Если Ассемблер выдаст сообщения об ошибках, то нужно исправить исходную программу с помощью редактора и заново ее оттранслировать.

3 Для получения выполняемой программы необходимо в командную строку набрать имя компоновщика TLINK.EXE и имя вашего объектного файла NAME.OBJ:

TLINK.EXE         NAME.OBJ

В текущем каталоге появятся файл – NAME.EXE и файл, содержащий таблицу имен и размеров сегментов NAME.MAP.

4 Выделите курсором исполняемый файл NAME.EXE и нажмите ENTER. Такое исполнение программы возможно при явных результатах или при полной уверенности в ее безошибочной работе.

 

Контрольные вопросы

          1. Структура программы на языке ассемблера.

2.     Этапы выполнения программы.

3.     Функции вывода 9h и 2h int 21h.

4.     Как создается исходный файл?

5.     Расширение исходного файла.

6.     Имя транслятора.

7.     Что делает транслятор?

8.      Какие выходные файлы получаются в результате трансляции? С какими расширениями?

9.      Пример командной строки запуска транслятора.

10. Имя компоновщика.

11. Какие файлы являются входными при компоновке?

12. Какие файлы являются выходными при компоновке?

13. Какое расширение имеет исполняемый файл?

14. Пример командной строки запуска компоновщика.

15.Как можно посмотреть файл листинга?

 

2 Лабораторная работа 2.  Работа с отладчиком TURBO DEBUGGER (TD)

Цель работы: изучить правила описания простых типов данных  и основные моменты работы с отладчиком TD.

     Задания.

1 Наберите исходный текст программы согласно варианту:

Data

segment

 

Mess

DB

‘ Директивы данных $’

Pa

DB

Pb

DW

 

Pc

DD

         

Mas

DB

          данные из вариантов заданий

Pole

DB

 

Adr

DW

 

Adr_full

DD

 

Data

ends

 

 

 

 

code

segment

 

 

assume

cs:code, ds:data

start:

 

 

 

mov

AX, data

 

mov

DS, AX

 

mov

DX, offset mess

 

mov

AH, 9h

 

int

21h

 

mov

AX, 4c00h

 

int

21h

code

ends

 

 

end

Start

Получив загрузочный модуль, запустите его в Турбо отладчике (TD). В окне DUMP просмотреть сегмент данных, найти все переменные, заданные в вашем варианте, и объяснить местоположение и занимаемый объем этой переменной. Вы ответственны не только за описание переменной в сегменте данных, но и за каждый байт памяти.

2 Набрать в кодовом сегменте команды:

mov

AL,

Pa

; AL = ?

mov

BX,

Pb

; BX = ?

mov

DL,

byte ptr Pb

; BL = ?

mov

CX,

word ptr Pc

; DX = ?

mov

SI,

word ptr Pc+2

; CX = ?

mov

CL,

byte ptr Pc

; DL = ?

mov

DH,

byte ptr Pc+1

; DH = ?

; работа с регистром флагов

mov

AL,

0FFh

; AL = ?

add

AL,

1

; AL = ? (0FFh + 1)

mov

AL,

5

; AL = ?

sub

AL,

0FEh

; AL = ? (5 - 0FEh)

; работа со стеком

push

BX

 

; (BX) - >  в стек

push

Pc

 

; (Pc) - > в стек

pop

DI

 

; слово из стека -> в DI

pop

Pb

 

; слово из стека -> в Pb

В отладчике посмотреть результат выполнения этих команд

Варианты заданий:

1.

Pa

Db

73H

8.

Pa

db

5BH

 

Pb

Dw

0AE21H

 

Pb

dw

0BA21H

 

Pc

Dd

38EC76A4H

 

Pc

dd

0FA4A32BCH

 

Mas

Db

10 dup(1),2,3

 

Mas

db

4,5,6,5 dup(0)

 

Pole

Db

5 dup(?)

 

Pole

db

6 dup(?)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

2.

Pa

Db

67H

9.

Pa

db

4AH

 

Pb

Dw

4AEFH

 

Pb

dw

0DEFCH

 

Pc

Dd

12DC4567H

 

Pc

dd

81ADFF06H

 

Mas

Db

5,6,7,8

 

Mas

db

5 dup(1),2,3,3 dup (4)

 

Pole

Db

6 dup(0)

 

Pole

db

6 dup(“ “)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

3.

Pa

Db

4DH

10

Pa

db

7FH

 

Pb

Dw

0ED56H

 

Pb

dw

0ACDEH

 

Pc

Dd

32AF8DD7H

 

Pc

dd

10B0A488H

 

Mas

Db

4,3,5,4 dup(0)

 

Mas

db

3 dup (0),1,2,3,4 dup(0)

 

Pole

Db

6 dup (?)

 

Pole

db

5 dup(32)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

4.

Pa

Db

5DH

11

Pa

db

0BCH

 

Pb

Dw

0A1A3H

 

Pb

dw

903FH

 

Pc

Dd

3 dup(4),5,6

 

Pc

dd

6CAA3E41H

 

Mas

Db

4,3,5, 4 dup(0)

 

Mas

db

1,2,3, 4 dup(4)

 

Pole

Db

5 dup(?)

 

Pole

db

5 dup(?)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

5.

Pa

Db

62h

12

Pa

db

0FBH

 

Pb

Dw

7ED1H

 

Pb

dw

54ADH

 

Pc

Dd

0EE45DA31H

 

Pc

dd

0E04365FAH

 

Mas

Db

1,2, 6 dup(3),0

 

Mas

db

3 dup(0), 4 dup(1),2,3

 

Pole

Db

5 dup(0)

 

Pole

db

5 dup(?)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

6.

Pa

Db

0FFH

13

Pa

db

11H

 

Pb

Dw

4ADEH

 

Pb

dw

4D2DH

 

Pc

Dd

0C23891F5H

 

Pc

dd

98ADF156H

 

Mas

Db

4 dup(0),1,2,3

 

Mas

db

5 dup(0),1,2,3

 

Pole

Db

3 dup(‘ ‘)

 

Pole

db

3 dup(?)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

7.

Pa

Db

0AEH

14

Pa

db

10H

 

Pb

Dw

63BCH

 

Pb

dw

1A2DH

 

Pc

Dd

63BCDEF3H

 

Pc

dd

55AEF2C8H

 

Mas

Db

9,8,3 dup(0)

 

Mas

db

1,2,3,4,5,6

 

Pole

Db

5 dup(“ “)

 

Pole

db

5 dup(0)

 

Adr

Dw

Pc

 

Adr

dw

Pc

 

Adr_full

Dd

Pc

 

Adr_full

dd

Pc

 

 

 

 

 

 

 

 

           Методические рекомендации по выполнению лабораторной работы

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

         Существуют следующие поддерживаемые TASM директивы данных:

DB (Define Byte)

резервирование памяти для данных размером 1 байт;

DW (Define Word)

резервирование памяти для данных размером 2 байта;

DD (Define Double word)

резервирование памяти для данных размером 4 байта;

DF (Define Far word)

резервирование памяти для данных размером 6 байт;

DP(Define Pointer)

резервирование памяти для данных размером 6 байт;

DQ(Define Quarter word)

резервирование памяти для данных размером 8 байт;

DT(Define Ten Bytes)

резервирование памяти для данных размером 10 байт.

Директивы данных имеют следующий формат:

[Имя ] мнемоника директивы [выражение] [;комментарий].

При определении переменной без присваивания ей начального значения надо указывать в поле выражения вопросительный знак (?).Например:

А db ? - неинициализированная переменная А (содержимое выделенного участка физической памяти в 1 байт изменяться не будет).

A db 10011011b - инициализированная переменная (транслятор выделяет 1 байт памяти переменной А и записывает указанное значение в память).

Порядок размещения данных в памяти напрямую связан с логикой работы микропроцессора с данными. Микропроцессоры  INTEL требуют следования данных в памяти по принципу: младший байт по младшему адресу.

Отладчик Turbo Debugger (TD) представляет собой оконную среду отладки программ на уровне исходного текста на многих языках программирования и в том числе на ассемблере. Он позволяет определить причину и место логической ошибки.

Основную часть экрана отладчика занимают одно или несколько окон. В каждый момент времени активным может быть только одно из них. Активизация любого окна производится щелчком мышью в любой видимой точке окна. Управление работой отладчика ведется  с помощью системы меню. Имеется два типа таких меню:

- глобальное меню – находится в верхней части экрана и доступно постоянно, вызов клавишей F10;

     - локальное меню - для каждого окна отладчика можно вызвать его собственное меню, которое учитывает особенности этого окна, клавиши ALT-F10.

Из четырех режимов чаще всего вам придется работать в режиме пошагового выполнения программы. В этом режиме вы можете выполнить программу по командам, при этом можно наблюдать результат исполнения каждой команды. Для активизации этого режима нужно нажать клавиши F7 (процедуры также выполняются по шагам) или F8 (процедура отрабатывается как одна команда). В этом режиме полезно использовать окно CPU, которое можно вызвать через меню VIEW|CPU.

Это окно отражает состояние микропроцессора и состоит из 5 подокон:

-         окна с исходной программой в дизассемблированном виде. Это та же программа, что и в окне MODULE, но уже в машинном коде. Пошаговую отладку можно производить прямо в этом окне;

-         REGISTERS – окна регистров микропроцессора, отражающего текущее состояние регистров;

-         окна флагов, которое отражает текущее состояние флагов микропроцессора;

-         окна стека STACK, отражающего содержимое памяти, выделенной   для стека;

-         окна с дампом памяти DUMP, отражающего содержимое области памяти данных.

В окне отладчика под названием MODULE вы увидите исходный текст программы с курсором выполнения (в виде треугольника).

Исходный модуль должен быть оттранслирован с опцией /zi:

Tasm /zi имя_исходного_модуля

Компоновка модуля должна быть осуществлена с опцией /v:

Tlink /v  имя_объектного_модуля

Запуск отладчика производить из командной строки с указанием исполняемого модуля программы:

Td имя_исполняемого_модуля.

        

Контрольные вопросы

1.      Как размещаются в памяти байты?

2.      Как размещаются в памяти слова, двойные слова?

3.      С какого байта адресуются слова, двойные слова?

4.      Как размещается в памяти полный адрес переменной?

5.      Какие операторы используются в команде ассемблера, если размеры регистров и переменных не одинаковы?

6.      Какие флаги устанавливаются при получении отрицательного, нулевого результата?

7.      Какие регистры и сегменты участвуют при выполнении команд PUSH и POP?

3 Лабораторная работа 3. Передача управления в программе

Цель работы: изучить способы программирования нелинейных алгоритмов.

Задания

         1 Перед выводом массива В на экран вывести текстовую строку: ”Это второй массив В”, т.е. на экране должно быть:

Это второй массив В 1 2 3 4 5

Элементы массива вывести через пробелы (или запятую).

         2 Измените количество элементов в массивах, введите необходимые изменения в программу:

         - измените данную программу, организовав в теле программы лишь один цикл;

         - изменить данную программу в программу для пересылки массива слов;

         - напишите программу для преобразования массива байтов в массив слов;

;сегмент

данных

 

A

db

1,2,3,4,5,6

B

dw

3 dup(?)

; сегмент

кодов

 

(ваша программа);

         - разработать программу сложения двух массивов байтов A и B, сумму сохранить в массиве C, взяв за основу рассмотренные примеры.

; сегмент

данных

 

A

db

1,2,3,4

B

db

5,6,3,1

C

db

4 dup(?)

         3 Заданы два массива байтов А и В, в третий массив нужно выбрать максимальные элементы, сравнивая поэлементно. Напишите программу, любой ваш вариант принимается.

;в сегменте

данных

 

A

DB

7,5,9,3

B

DB

4,8,2,6

C

DB

4 dup(?)

После выполнения вашей программы на экране мы должны получить следующий результат:

Массив С 7 8 9 6

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

Массив С 4 5 2 3

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

;в сегменте

данных

 

A

DB

9,8,7,6,5,4

В результате будем иметь:

Максимальный элемент массива А – 9.

А результат этот получился после запуска вашего EXE-файла.

6 Измените предыдущую программу для поиска минимального элемента в заданном массиве байтов.

И, естественно, результат будет другой:

Минимальный элемент массива А – 4.

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

         7 Задан массив А.

A

DB

1,1,-2,-4,6

 

DB

2,-5,2,-2,5

 

DB

3,-3,-3,4,4

 

DB

5,-5,6,-7,7

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

1 1 0 0 6

2 0 2 0 5

3 0 0 4 4

5 0 6 0 7

8 Нарисовать звездочками (*) в текстовом режиме фигуры, изображенные на рисунке 1, используя функцию 2 прерывания INT 21h.

Рисунок 1

Методические рекомендации по выполнению лабораторной работы

В языке ассемблера место, куда необходимо передать управление, определяется меткой. Метка – это символическое имя, обозначающее определенную ячейку памяти, предназначенное для использования в качестве операнда в командах передачи управления

Команды передачи управления делятся на группы:

-         команды организации цикла;

-         команды безусловной передачи управления;

-         команды условной передачи управления.

Команды организации цикла

LOOP – команда организации цикла со счетчиком в регистре CX.

LOOP метка

Количество повторений цикла задается значением в регистре СХ перед входом в последовательность команд, составляющих тело цикла

Алгоритм работы: выполняется декремент содержимого регистра CX, затем анализ регистра CX.  Если CX=0, то управление передается следующей за LOOP команде, а если CX > 0, то – метке, которая указана в качестве операнда LOOP.

Выполнение команды не влияет на состояние флагов.

Команды безусловной передачи управления:

1. Команда безусловного перехода - JMP метка;

2. Вызов процедуры и возврата из процедуры - CALL имя_процедуры и RET;

3. Вызов программных прерываний - INT номер_прерывания, возврат из программных прерываний – IRET и команда INTO - прерывание, если переполнение.

Команды условной передачи управления:

1 Команды перехода по результату команды сравнения: CMP операнд1, операнд2

Алгоритм работы: выполняется вычитание (операнд1-операнд2), затем в зависимости от результата выставляются флаги, операнд1 и операнд2 не изменяются, то есть результат не запоминается.

JE

операнд1 = операнд2

JNE

операнд1 <> операнд2

 

Без знака

Со знаком

Критерий условного перехода

 

JB/JNAE

JL/JNGE

операнд1 < операнд2

 

JBE/JNA

JLE/JNG

операнд1 <= операнд2

 

JA/JNBE

JG/JNLE

операнд1 > операнд2

 

JAE/JNB

JGE/JNL

операнд1 => операнд2

 

 

 

 

 

 

 

 

2 Команды перехода по состоянию определенного флага

JC

(JNC)

метка_перехода

JP

(JNP)

метка_перехода

JZ

(JNZ)

метка_перехода

JS

(JNS)

метка_перехода

JO

   (JNO)

метка_перехода

3 Команды перехода по содержимому регистра СХ

 JCXZ

метка_перехода

 

Порядок выполнения работы

Задана программа пересылки массива байтов А на место массива  байтов В.

sseg

segment

 

 

db

128 dup(?)

sseg

ends

 

dseg

segment

 

A

db

1,2,3,4,5

B

db

5 dup(?)

dseg

ends

 

cseg

segment

 

 

assume

ss:sseg, cs:cseg, ds:dseg

start:

 

 

 

mov

ax,dseg

 

mov

ds,ax

 

mov

si,0

 

mov

cx,5

M1:

 

 

 

mov

al, A[si]

 

mov

B[si],al

 

inc

Si

 

loop

M1

 

mov

cx,5

 

mov

si,0

M2:

 

 

 

 

mov

ah,2h

 

 

mov

dl,B[si]

 

 

int

21h

 

 

inc

Si

 

 

loop

M2

 

 

mov

ah,4ch

 

 

int

21h

 

cseg

ends

 

 

 

end

Start

 

 

 

 

 

 

Контрольные вопросы

1.      Какие команды условного перехода используются при операциях над числами со знаком?

2.      Какие команды безусловного перехода используются для обхода группы команд?

3.      Какие команды используются для организации цикла?

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

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

 

4 Лабораторная работа 4. Разработка программ с использованием логических команд и команд сдвига

Цель работы: изучить организацию работы с отдельными битами

          Задание

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

;в сегменте

данных

 

 

A

DB

01101011B

или

A

DW

0010111110101001B

 

 

 

 

 

 

 

 

 

 

         2. Измените программу для подсчета нулей.

         3. Задан массив байтов А из чисел со знаками. Напишите программу, подсчитывающую количество отрицательных элементов массива. Ваш любой вариант принимается. А теперь напишите с использованием команды TEST.

4. Измените программу для подсчета положительных элементов массива.

         5. Напишите программу преобразования двух неупакованных BCD-чисел в слове памяти в упакованное BCD-число в регистре AL.

          Методические рекомендации по выполнению лабораторной работы

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

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

ANDкоманда логического умножения И (конъюнкция) над битами операндов приемник и источник.

Формат команды: AND приемник, источник

OR -  команда логического сложения ИЛИ (дизъюнкция) над битами операндов приемник и источник.

Формат команды: OR приемник, источник

XOR - команда логического исключающего сложения ИЛИ над битами операндов приемник и источник. Формат команды: XOR приемник, источник

Результат вычисляется в соответствии с таблицей истинности логических операций.

Таблица 1

Приемник

Источник

AND

OR

XOR

0

0

0

0

0

0

1

0

1

1

1

0

0

1

1

1

1

1

1

0

TEST (“test – проверить”) команда логического сравнения посредством логического умножения И (конъюнкция) над битами операндов приемник и источник, но состояние операндов остается прежним, изменяются только флаги zf, sf, и  pf, что дает возможность анализировать состояние отдельных битов операнда без изменения их состояния.

Формат команды: TEST приемник, источник

NOT - команда логического отрицания каждого бита операнда источник.

Формат команды: NOT источник. Команда инвертирует все биты операнда источник: из 1 в 0, из 0 в 1. Выполнение команды не влияет на флаги.

Примеры.

1. mov AL, 1111 0000b    2.mov AL, 1111 0000b    3. mov  AL,  1111 0000b

and AL, 1010 1010b         or  AL, 1010 1010b          xor    AL,  1010 1010b

; результат 1010 0000b  ; результат 1111 1010b  ; результат     0101 1010b

         4. mov  AL, 11110000b           5. ; проверить число на четность

              not   AL ; AL=00001111b        test AL, 0000 0001b

                                                             jz  m

…     ; число нечетное

            m:    ; число четное

Из примеров видно, что команда AND может сбрасывать в 0 биты приемника, соответствующие  нулевым битам источника, команда OR - устанавливать в 1 биты приемника, соответствующие  единичным битам источника, а команда XOR – инвертировать биты приемника, соответствующие единичным битам источника.

Команды сдвига.

По принципу действия команды сдвига можно разделить на два типа:

         - команды линейного (логического SHL, SHR или арифметического SAL, SAR) сдвига;

         - команды циклического (простого ROL, ROR и через флаг переноса RCL, RCR) сдвига.

Все команды сдвига перемещают биты в поле операнда влево или вправо в зависимости от кода операции. Все команды сдвига имеют одинаковый формат: первым операндом является операнд-источник, вторым операндом является количество сдвигов. Количество сдвигов либо указывается непосредственно в команде, либо перед выполнением команды сдвига заносится в регистр CL. Например,

 

MOV CL,4

.386

SHL AX,1

SHL AX,CL

SHL AX,4 (для старших процессоров)

SHL – команда логического сдвига влево сдвигает содержимое операнда влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) записываются нули.

SHL операнд, счетчик_сдвигов

SHR - команда логического сдвига вправо сдвигает содержимое операнда вправо на количество битов, определяемое значением счетчик_сдвигов. Слева (в позицию старшего бита) записываются нули.

SHR операнд, счетчик_сдвигов

SAL  – команда арифметического сдвига влево сдвигает содержимое операнда влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) записываются нули.

         SAL операнд, счетчик_сдвигов

Команда SAL не сохраняет знака. Команда SAL полностью аналогична команде SHL.

SAR – команда арифметического сдвига вправо сдвигает содержимое операнда вправо на количество битов, определяемое значением счетчик_сдвигов. Слева (в позицию старшего бита) записываются нули, если сдвигается положительное число, и единицы, если сдвигается отрицательное число.

SAR операнд, счетчик_сдвигов

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

ROL – команда циклического сдвига влево сдвигает содержимое операнда влево на количество битов, определяемое значением счетчик_сдвигов. Сдвигаемые влево биты записываются в тот же операнд справа.

ROL операнд, счетчик_сдвигов

ROR – команда циклического сдвига вправо сдвигает содержимое операнда вправо на количество битов, определяемое значением счетчик_сдвигов. Сдвигаемые вправо биты записываются в тот же операнд слева.

ROR операнд, счетчик_сдвигов

RCL – команда циклического сдвига влево через флаг переноса сдвигает содержимое операнда влево на количество битов, определяемое значением счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса CF. Одновременно старое значение флага переноса CF вдвигается в операнд справа и становится значением младшего бита операнда.

RCL операнд, счетчик_сдвигов

RCR – команда циклического сдвига вправо через флаг переноса сдвигает содержимое операнда вправо на количество битов, определяемое значением счетчик_сдвигов. Старое значение флага переноса CF вдвигается в операнд слева и становится значением старшего бита операнда

RCR операнд, счетчик_сдвигов

Контрольные вопросы

1. Какие флаги изменяются при выполнении логических команд?

2. Куда попадает разряд выходящий из регистра или ячейки памяти при выполнении команды сдвига?

 

5 Лабораторная работа 5. Разработка программ с использованием арифметических команд и команд обработки строк

Цель работы: изучить общие свойства команд двоичной и двоично-десятичной арифметики, цепочечных команд

          Задание

         1 Написать программу вычисления по формуле:

1. y= (a+b)2 /(c-d)2.

2. y= (a2+b) /(c-d)2.

3. y= (a+b2) /(c2-d)2.

4. y= (a2+b2) /(c-d)2.

5. y= (a+b)3 /(c2-d2).

6. y= (a3+b) 2 /(c-d2)2.

7. y= (a+b)3 /(c2-d) 3.

8. y= (a2+b3) /(c-d)3.

         1.2 Показать результат в отладчике

         1.3 Выдать результат на экран

- в двоичном  виде

- в десятичном  виде

- в шестнадцатеричном  виде

         2 Напишите программу пересылки символов из одной строки в другую

 

; в сегменте данных

 

 

str_source

DB

‘Строка_пересылаемая’,’$’

;строка-источник

str_dest

DB

20 dup(?)

;строка-приемник

         3 Напишите программу посимвольного (поэлементного) сравнения двух строк.

         4 Напишите программу поиска  заданного символа в заданной строке, осуществите замену этого символа на другой, введенный с клавиатуры или заранее определенный в памяти.

         5 Напишите программу, которая сравнивает две строки и первый несовпавший элемент помещает в регистр AL.

 

         Методические рекомендации по выполнению лабораторной работы

Команды сложения

ADD - команда сложения. Формат команды: ADD приемник, источник.

ADС - команда сложения с переносом. Формат команды: ADС приемник, источник.

При исполнении команды сложения ADD результат заносится в операнд- источник. При исполнении команды ADC результат также заносится в операнд- источник, но при сложении используется флаг переноса CF.

Состояние флагов после выполнения команд ADD и ADC: могут измениться значения CF, PF, AF, ZF, SF, ОF.

ААА - ASCIIкоррекция результата сложения. Команда ААА корректирует результат сложения для представления в кодах ASCII. Она преобразует содержимое регистра AL в правильную неупакованную десятичную цифру.

Команда используется в следующем контексте:

add    AL, BL

aaa

DAA - десятичная коррекция результата сложения Команда DAA корректирует сложение для представления в десятичной форме. Она преобразует содержимое регистра AL в две правильные упакованные десятичные цифры. Используется в контексте:

add    AL, BL

daa

Команды AAA и DAA не требуют наличия операндов, т.к. предполагают, что корректируемое значение находится в регистре AL.

INC увеличение операнда на 1. Формат команды: INC операнд

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

Состояние флагов после выполнения команды: меняются  PF, AF, ZF, SF, ОF.

 

Команды вычитания.

SUB - команда вычитания. Формат команды: SUB приемник, источник

SBB - команда вычесть с заемом. Формат команды: SBB приемник, источник

Использование команд SUB и SBB аналогичны командам сложения. Воздействуют на те же 6 флагов.

AAS - ASCIIкоррекция результата вычитания. Команда AAS корректирует результат вычитания для представления в кодах ASCII.

DAS - десятичная коррекция результата вычитания. Команда DAS корректирует результат вычитания для представления в десятичной форме.

Команды AAS и DAS аналогичны командам AAA и DAA. Используются в контексте:

sub    AL, BL                 или             sub    AL, BL

aas                                          das

DEC – уменьшение операнда на 1. Формат команды: DEC операнд

Команда DEC вычитает единицу из содержимого регистра или ячейки памяти.

NEG - команда изменения знака операнда. Формат команды: NEG операнд

Команда вычитает значение операнда из нулевого значения. Пусть значение содержимого регистра AL нужно вычесть из 100. Так как цифра 100 не может служить операндом приемником, то запись

sub    100, AL      

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

neg    AL

add    AL, 100

Состояние флагов после выполнения команды: меняются значения  OF, SF, ZF, AF, PF и СF = 1, если операнд ненулевое число, в противном случае, они равны нулю.

СМР - Команда сравнения. Формат команды: СМР приемник, источник.

Команда вычитает источник из приемника и в зависимости от результата устанавливает флаги; операнды приемник и источник не меняются.

Состояние флагов после выполнения команды: меняются  значения  OF, SF, ZF, AF, PF и СF.

 

Команды умножения

MUL - Команда умножения чисел без знака. Формат команды: MUL источник.

IMUL - Команда целого умножения чисел со знаком. Формат команды: IMUL источник.

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

В качестве второго операнда используется содержимое регистров AL (для байтов) , AX (для слов) или EAX (для двойных слов). Произведение имеет двойной размер и возвращается следующим образом: умножение байтов возвращает 16-битовое произведение в регистрах АН (старший байт) и AL (младший байт); умножение слов возвращает 32-битовое произведение в регистрах DX (старшее слово) и АХ (младшее слово); умножение двойных слов возвращает 64-битовое произведение в регистрах EDX (старшее двойное слово) и EАХ (младшее двойное слово).

Состояние флагов после выполнения команды MUL:

CF = OF = 0, если старшая половина произведения равна нулю, в противном случае, они равны единице.

Состояние флагов после выполнения команды IMUL:

CF = OF = 0, если старшая половина произведения представляет собой лишь расширение знака младшей половины, в противном случае, они равны единице.

ААМ – ASCII коррекция результата умножения. Команда преобразует результат предшествующего умножения  байтов в два правильных неупакованных десятичных операнда.

 

Команды деления.

DIV - Команда деления без знака. Формат команды: DIV источник

IDIV - Команда деления чисел со знаком. Формат команды: IDIV источник

Делитель размером в байт, слово или двойное слово находится в регистре общего назначения или в ячейке памяти. Делимое должно иметь двойной размер, оно извлекает из регистров АН и АL (при делении на 8-битовое число), из регистров DX и AX (при делении на 16-битовое число) или из регистров EDX и EAX (при делении на 32-битовое число). Результат возвращается следующим образом: если источник представляет собой байт, то частное возвращается в регистр AL, а остаток в регистр АН. Если источник представляет собой слово, то частное возвращается в регистр АХ, а остаток - в DX и, если источник представляет собой двойное слово, то частное возвращается в регистр EАХ, а остаток - в EDX.

AAD - ASCII коррекция результата деления. Исполняется непосредственно перед операцией деления. Команда преобразует неупакованное делимое в двоичное число и загружает его в регистр AL.

 

Команды обработки строк.

Система команд микропроцессора имеет очень интересную группу команд, позволяющих производить действия над блоками элементов от 1 Байта до 64 Кбайт (для 32-разрядных микропроцессоров – до 4 Гбайт). Это  цепочечные команды или команды обработки строк символов. Эти блоки логически могут представлять собой последовательности элементов с любыми значениями, хранящимися в памяти в виде двоичных кодов. Микропроцессор всегда предполагает, что строка-приемник находится в дополнительном сегменте (адресуемом посредством сегментного регистра ES), а строка-источник – в сегменте данных (адресуемом посредством сегментного регистра DS). Микропроцессор адресует строку - приемник через регистр DI, а строку-источник - через SI. Допускается переопределять сегмент для строки-источника, для строки-приемника этого делать нельзя.

Особенность работы цепочечных команд состоит в том, что они автоматически выполняют приращение или уменьшение содержимого регистров DI и SI в зависимости от используемой цепочечной команды. Что именно происходит с этими регистрами, определяется состоянием флага DF, которым управляют команды CLD и STD.

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

 

 

Пересылка строк:

 

 

 

 

MOVSB

MOVS адрес-приемника, адрес_источника

=>

MOVSW

 

 

MOVSD

Сравнение строк:

 

 

 

 

CMPSB

CMPS адрес-приемника, адрес_источника

=>

CMPSW

 

 

CMPSD

Сканирование строк:

 

 

 

 

SCASB

SCAS адрес-приемника

=>

SCASW

 

 

SCASD

Загрузка элемента из строки:

 

 

 

 

LODSB

LODS  адрес_источника

=>

LODSW

 

 

LODSD

Сохранение элемента в строке:

 

 

 

 

STOSB

STOS адрес-приемника

=>

STOSW

 

 

STOSD

 

Контрольные вопросы

1. Какие флаги изменяются при выполнении арифметических команд?

2. Где находятся сомножители и результат при выполнении команды умножения?

3. Где находятся делимое, делитель и результат при выполнении команды деления?

4. В каком регистре хранится длина строки в цепочечных командах? 

5. Как адресуются строковые операнды?

 

6 Лабораторная работа 6. Использование системных функций в прикладных программах

 

Цель работы: изучение системных функций ввода с клавиатуры, вывода на экран, работы с файлами средствами DOS  и BIOS, получение навыков их использования.

Задание.

Написать программы:

1 Ввода  строки  с клавиатуры с помощью ф.0Ah int 21h (ф.3Fh int 21h).

2 Ввода пароля (с помощью ф.0 int 16h, ф.7, ф.8 int 21h) и проверки его.

3 Проверки нажатия клавиши Enter (F1, Home).

4 Организации паузы и продолжения программы по нажатию клавиши (любой, конкретной).

5 Ввода строки и замены байта 0Dh на 0.

6 Ввода строки с клавиатуры с помощью ф.1 int 21h, ф.0 int 16h.

7 Вывода символа с помощью ф.2 int 21h (ф.9 int 10h).

8 Вывода группы одинаковых символов с помощью ф.21 int 21h (ф.9 int 10h).

9 Вывода массива на экран.

10 Вывода горизонтальной линии с помощью ф.10 int 10h (ф.14 int 10h, ф.9 int 10h).

11 Вывода текстовой строки с помощью ф.9 int 10h (ф.40 int 21h).

12 Вывода рамки с помощью ф.9 int 21h (ф.40h int 21h, ф.2 int 21h, ф.10 int 10h).

13  Записать в файл текстовую строку.

14  Определить длину файла.

15  Прочитать файл и вывести его содержимое на экран.

16  Поменять в файле 10-й байт.

17  Прочитать в файле 5-й байт и вывести его на экран.

18  Скопировать один файл во второй.

19  Скопировать файл начиная с 20-го байта во второй.

20 Прочитать файл и записать в последний байт контрольную сумму.

21 Сравнить два файла на идентичность.

22 Объединить два файла.

23 Определить номер заданного байта.

24 Переименовать файл и установить в нем время и дату создания.

25 Переименовать файл и поменять в нем атрибут.

 

  Методические рекомендации по выполнению лабораторной работы

Обзор системных функций ввода с клавиатуры

Ввод с клавиатуры обслуживается прерываниями BIOS (INT 16h) и прерываниями DOS (INT 21h) функции 1, 7, 8, 0Ah, 3Fh).

Функция 0h INT 16h ожидает нажатия клавиши. После нажатия клавиши в регистр AL (если нажата символьная клавиша, имеющая ASCII-код) заносится ASCII-код клавиши или 0 (если нажата функциональная клавиша), в регистр AH заносится скан-код клавиши.

По содержимому регистра AL можно определить, какая нажата клавиша, символьная или функциональная.

key:   mov   ah, 0  ; ожидание нажатия клавиши

int      16h    ; вызов bios

cmp   al, 0   ; проверка нажатия

je       m1     ; функциональной клавиши

jmp    key    ; не функциональная клавиша

m1:    ....               ; да, функциональная клавиша

Функция 1h INT 16h осуществляет чтение информации о состоянии буфера клавиатуры; если буфер пуст, возвращает во флаге нуля 1; если буфер не пуст, возвращает во флаге нуля 0; в AX - очередной символ, остальные - в буфере.

Функция 1h INT 21h выполняет ввод символа с клавиатуры, отображает его на экране и выполняет проверку на Ctrl-Break. После ввода символа в AL будет ASCII-код символа.

mov   AH, 1h

int      21h

Функция 7h INT 21h выполняет ввод символа с клавиатуры без отображения на экране. После выполнения функции в регистре AL будет ASCII-код символа.

mov   AH, 7h

int      21h

Функция 8h INT 21h аналогична функции 7h, но, кроме того, выполняет проверку на Ctrl-break.

mov   AH, 8h

int      21h

Для считывания функциональной клавиши с помощью функций 1, 7, 8 нужно выполнять две операции считывания кода клавиши. Первая операция заносит в регистр AL 0, вторая операция считывания - в регистр AL скан-код (расширенный код).

key:   mov   AH, 8          ; ждать нажатия клавиши

int      21h

cmp   AL, 0          ; расширенный код?

jmp    error            ; нет, выдать сообщение об ошибке

mov   AH, 8          ; считать скан-код

int      21h

cmp   AL, 33h       ; нажата клавиша f1?

je       f1                ; да

jmp    key              ; нет

error: ...

Функция 0Ah INT 21h выполняет ввод строки с клавиатуры в буфер. Адрес буфера загружается в регистр DX. В сегменте данных нужно описать буфер и указать его размер. Первый байт буфера и должен содержать размер. После выполнения функции второй байт будет содержать фактическую длину вводимой строки, которая заканчивается кодом возврата каретки.

; в сегмент данных

buf    db     22, 21 dup(?)

; в сегмент кода

mov   AH, 0ah

lea     DX, buf

int      21h

Введенная строка начинается в памяти с адреса BUF+2.

Функция 3Fh INT 21h выполняет ввод данных с устройства. В качестве дескриптора устройства нужно задать 0 (стандартный ввод - клавиатура). В регистре CX указывается количество вводимых байтов, в регистр DX загрузить адрес буфера.

После выполнения функции в AX будет фактическое число введенных байтов.

; в сегмент данных

buf    db     20 dup (?)

; в сегмент кода

mov   AH, 3fh

mov   BX, 0          ; дескриптор клавиатуры

mov   CX, 20

lea     DX, buf

int      21h

mov   CX, AX      ; запомнить в CX фактическое число введенных байтов

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

Обзор системных функций вывода на экран

Вся информация, выводимая на дисплей, должна быть представлена в ASCII кодах. BIOS обслуживает 3 функции (9, 10, 14) вывода символа на дисплей.

Функция 9 int 10h осуществляет вывод символа с атрибутом в текущую позицию курсора. При вызове функции: BH – номер видеостраницы (текстовые режимы: 0-текущая страница), BL - атрибуты символа, CX - число повторений символа при выводе, AL - выводимый символ:

mov   AH, 9h

mov   BH, 0

mov   BL, 07h

mov   CX, 1

mov   AL, 'a'

int      10h

Функция 10 INT 10h осуществляет вывод символа в текущую позицию курсора без изменения атрибута. При вызове функции: BH - номер видеостраницы, 0 - текущая страница. CX - число повторений символа при выводе. AL - выводимый символ:

mov   AH, 10

mov   BH, 0

mov   CX, 1

mov   AL, 'A'

int      10h

При использовании функции 09h и 10h следует помнить, что данные функции не перемещают курсор при выводе символа (или группы символов).

Функция 14 INT 10h осуществляет вывод символа на экран и перемещение курсора в следующую позицию. При вызове функции: AL - выводимый символ. BH - номер страницы:

mov   AH, 14

mov   AL, 'A'

mov   BH, 0

int      10h

Функции вывода на экран средствами DOS:

Функция 2 INT 21h осуществляет вывод символа на дисплей с перемещением курсора.

При вызове: DL – символ:

mov   AH, 2

mov   DL, 'A'

int      21h

Функция 9 INT 21h осуществляет вывод строки на экран.

При вызове: DS:DX - адрес строки, которая должна заканчиваться знаком доллара. Курсор перемещается в конец строки:

; в сегментe данных

string DB    'Текстовая строка $'

; в сегментe кода

mov   AH, 9

lea     DX, string

int      21h

Функция 40h INT 21h осуществляет запись в файл или вывод данных на устройство.

При вызове: BX - логический номер файла или устройства. Экран имеет логический номер 01. CX - число выводимых символов, DS:DX - адрес буфера, откуда берутся данные.

При возврате: Если CF = 0, то в AX - число фактически записанных байтов. Если СF=1, то в AX - код возврата (код ошибки).

Обозначение DS:DX, описанное при вызове какой-либо функции, используется следующим образом. В сегменте данных или кодовом сегменте должна быть описана строка, адрес которой загружается в регистр DX с помощью команды:

lea     DX, <имя строки>                 ; либо

mov   DX, offset <имя строки>

Регистр DS должен содержать адрес сегмента, где расположена строка:

; в сегментe данных

     string DB    'Текстовая строка '

stringlen      EQU  $-string

; в сегмент кода

mov   AH, 40h

mov   BX, 1                    ; логический номер дисплея

mov   CX, stringlen

mov   DX, offset string

int      21h

Пример. Вывод горизонтальной линии:

mov   CX, 10

m1:    mov   AH, 14

mov   AL, 196                ; ASCII код '-'

mov   BH, 0

int      10h

loop   m1

Пример. Вывод горизонтальной линии со сменой атрибута. Желтые символы на синем фоне:

mov   AH, 9

mov   BH, 0                             ; текущая страница

mov   CX, 15

mov   AL, '='                           ; выводимый символ

mov   BL, 0001111Ob

int      10h

Обзор системных функций работы с файлами

Все эти функции относятся к расширенной версии DOS, где обращение к файлам осуществляется с помощью дескриптора. Дескриптор или логический номер файла присваивается операционной системой файлу в результате создания или открытия файла, заданного в формате ASCIIZ-строки. ASCIIZ-строка - символьная строка, завершающаяся нулем. Дескриптор файла записывается в регистр АХ , и его следует сохранить в ячейке памяти.

Первые пять номеров (0-4) присвоены стандартным устройствам:

0 - стандартный ввод (CON).

1 - стандартный вывод (CON).

2 - стандартная ошибка (CON).

3 - стандартный вспомогательный порт (AUX).

4 - стандартный принтер (PRN).

Мы можем использовать дескриптор 0 для ввода с клавиатуры, дескрипторы 1 или 2 - для вывода на экран.

При работе с файлами успешная операция устанавливает флаг CF в 0. Если операция не выполнилась, то флаг CF устанавливается в 1, а в регистр AX помещается код ошибки.

Таблица 2 - Коды ошибок

Код ошибки

Описание

Код ошибки

Описание

01

02

03

04

 

05

06

07

 

08

09

ошибка номера функции

файл не найден

путь доступа не найден

открыто слишком много файлов

доступ не разрешен

ошибка файлового номера

блок управления памятью разрушен

недостаточно памяти

ошибка адреса

10

11

12

13

15

16

 

17

18

ошибка оборудования

ошибка формата

ошибка кода доступа

ошибка данных

ошибка дисковода

попытка удалить оглавление

не то устройство

нет больше файлов

Функции 3Ch и 5Bh позволяют создать файл, с заданной спецификацией (путь и имя файла в формате ASCIIZ-строки). Различие функций в том, что функция 3Ch уничтожает имеющийся файл и создает новый с тем же именем, а функция 5Bh завершается с CF=1, если файл с таким именем существует.

Пример:

; в  сегмент  данных поместить имя файла и зарезервировать ячейку для дескриптора

fname DB    'F1.TXT',0

handle         DW   ?

 . . .

mov   AH, 3Ch     ; запрос на создание

mov   CX, 0          ; обычного файла

lea     DX, fname   ; адрес имени файла

int      21h

jc       err               ; переход по ошибке

mov   handle, AX; сохранить дескриптор

В этом примере в регистр CX заносится атрибут файла. Могут использоваться следующие атрибуты:

01h - файл только для чтения

02h - скрытый файл

04h - системный файл

Функция 3Dh - позволяет открыть уже имеющийся файл.

Пример:

mov   AH, 3Dh               ; функция открытия файла

mov   AL, 02                  ; для ввода-вывода

lea     DX, fname

int      21h

mov   handle, AX

При открытии файла в регистр AL заносится код доступа:

0 - открыть файл только для ввода;

1 - открыть файл только для вывода;

2 - открыть файл для ввода и вывода.

Функция 42h используется для организации прямого доступа к произвольному месту файла. Указатель можно установить на начало файла (AL=0), в текущее положение (AL=1) и в конце файла (AL=2). Кроме того, значение смещения указателя (со знаком) заносится в регистры CX (старшая половина) и DX (младщая половина).

Пример:

mov   BX, handle

mov   AH, 42h                ; установить указатель

mov   AL, 2                    ; на конец файла

mov   CX, 0

mov   DX, 0

int      21h

Функция 3Fh используется для чтения из файла или устройства. При попытке чтения за концом файла AX=0.

Пример:

mov   AH, 3Fh               ; функция чтения

mov   BX, handle            ; установить дескриптор

mov   CX, 80                 ; сколько читать

lea     DX, buf                ; и куда

int      21h

mov   CX, AX                ; сколько фактически прочитали

Функция 40h используется для записи в файл или на устройство.

Пример:

mov   AH, 40h                ; функция записи

mov   BX, handle

mov   CX, 80                 ; сколько писать

lea     DX, buf                ; откуда

int      21h

Функция 43h используется для получения (AL=0) или установки (AL=1) атрибутов файла.

Пример:

mov   AH, 43h                ; функция работы с атрибутами

mov   AL, 1                    ; установка атрибутов

mov   CX, 1                   ; "только для чтения"

mov   DX, offset fname  ; адрес имени файла

int      21h

Функция 56h используется для переименования файла.

Пример:

; настроить сегментный регистр ES на сегмент данных

push  DS

pop   ES

; переименовать файл

mov   AH, 56h                ; функция переименования

mov   DX, offset oldname        ; адрес старого имени

mov   DI, offest newname        ; адрес нового имени

int      21h

; в сегмент данных

oldname      db     'fl.txt',0

newnamt      db     'newf.txt',0

Функция 57h используется для получения (AL=0) и установки (AL=1) даты и времени создания файла. Время записывается в регистр СХ и вычисляется по формуле:

CX= часы*2048+ минуты*32+секунды/2

Дата записывается в регистр DX и вычисляется по формуле:

DX=(год-1980)*512+месяц*32+день.

Пример:

; изменить время и дату создания файла

mov   AH, 57h      ; функция даты/времени

mov   AL, 1          ; установить дату/время

mov   BX, hаndle  ; установить дескриптор

mov   CX, 0          ; очистить cx

or      CX, seс       ; добавить секунды

or      CX, min      ; добавить минуты

or      CX, hour     ; добавить часы

xor    DX, DX      ; очистить DX

or      DX,day       ; добавить день

or      DX, mon     ; добавить месяц

or      DX, year     ; добавить год

int      21h

; в сегмент данных

sec              DW   6/2     ; 6 секунд

min    DW   15 * 32        ; 15 минут

hour   DW   16*2048      ; 16 часов

day             DW   25      ; 25 число

mon   DW   3*32            ; Март

year   DW   25*512        ; 25 лет от 1980г, т.е. 2005 г.

Функция 3Eh используется для закрытия файла. Эта операция необходима для коррекции оглавления и таблицы FAT.

Пример:

mov   AH, 3Eh      ; функция закрытия

mov   BX, handle

int      21h

Функция 41h используется для удаления файлов (за исключением файлов с атрибутом 'только чтение')

mov   AH, 41h      ;  функция удаления

lea     DX, fname   ;  адрес имени файла

int      21h             ;  вызов DOS

Работа с файлами может состоять из нескольких этапов:

- создания и открытие  файла;

- установить  указатель;

- определение длины файла;

- чтение нужного байта, блока, запись байта, блока, дополнение файла;

- закрытие файла;

- удаление файла.

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

Пример. Прочитать 10-й байт, открыть файл для чтения/записи

...

;  установить указатель на 10 байт

mov   AH, 42h                ; установить указатель

mov   BX, handle

mov   AL, 00                  ; на начало файла

mov   CX, 00

mov   DX, 10                 ; на 10-й байт

int      21h

; прочитать нужный байт

mov   ah, 3fh

mov   bx, HANDLE

lea     dx, BUF

mov   cx, 1

int      21h

; в сегмент данных

BUF  DB    ?

Пример 2. Найти символ "а" и определить его номер

;открыть файл

....

;определить длину файла

mov   AH, 42h                ; установить указатель

mov   BX, HANDLE

mov   AL, 2                    ; на конец файла

mov   CX, 00                 ; старшая половина смещения

mov   DX, 00                 ; младшая половина смещения

int      21h;

mov   FLEN, AX            ; запомнить длину файла

; установить указатель на начало файла

....

; прочитать файл в bufin

....

; поиск символа "а"

cld                        ; поиск осуществляется слева направо

mov   CX, FLEN  ; длина файла

mov   AL, 'A'        ; искомый символ

lea     DI, BUFIN  ; адрес строки

repne scasb          ; сканировать

jnz     m                ; символ найден?

dec    DI               ; да - уменьшить адрес

...                         ; вывести номер на экран m:    ...

; вывести сообщение что символ не найден

; закрыть файл

Контрольные вопросы

1. Чем отличаются функции 1, 7, 8 int 21h?

2. Что записывается в первый и во второй байт буфера при использовании ф.0Ah int 21h?

3. Как выполняется ввод при нажатии функциональной клавиши?

4. Чем отличается выполнение ф.0 int 16h и ф.7 int 21h?

5. Чем отличаются ф.0Ah и ф.3Fh int 21h?

6. С какого байта в буфере начинаются данные после использования ф.0Ah int 21h?

7. Чему равно значение последнего байта строки после использования ф.0Ah int 21h?

8. Фунцкии вывода символа на экран.

9. Функции вывода строки на экран.

10. Как определяется конец строки при использовании ф.9 и ф.40h int 21h?

11. Какие функции не перемещают курсор при выводе символа?

12. Какая функция вывода на дисплей меняет атрибут символа?

13. Что такое дескриптор файла?

14. Что такое ASCIIZ строка?

15. Дескрипторы стандартного ввода и стандартного вывода.

16. Как определяется успешность завершения какой-либо файловой операции?

17. Атрибуты файла.

18. Коды доступа при открытии файла.

19. Как определить длину файла?

20. Что делает функция закрытия файла?

21. Какие файлы нельзя удалить с помощью функции 41h?

 

Список литературы

1. Юров В.И. Assembler: Учебник для вузов. - СПб.: Питер, 2006.

2. Ирвин, Кип. Язык ассемблера для процессоров Intel. Пер. с англ. – М.: Издательский дом “Вильямс”, 2005.

3. Пирогов В.Ю. ASSEMBLER: Учебный курс. – М.: “Нолидж”, 2003 .

4. Пирогов В.Ю. Ассемблер на примерах.- СПб.: БХВ-Петербург, 2005.

5. Рудаков П.И., Финогенов К.Г. Язык ассемблера: уроки программирования.  – М.: ДИАЛОГ-МИФИ, 2001.

6. Юров В., Хорошенко С. Ассемблер.- С.-Пб.: "Питер" , 1999.

7. Зубков С.В. Assembler  для DOS, Windows и Unix. – М.: ДМК, 1999.

8. Финогенов К.Г. Самоучитель по системным функциям MS-DOS. - М.: МП "МАЛИП", 1993.