Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29196
Скачиваний: 1689
Часть I. Знакомьтесь: ассемблер
20
Листинг 2.2. Примеры использования оператора sub
mov al,10
sub al,7 ;al = 3; al — приемник, 7 — источник
mov ax,25000
sub ax,10000 ;ax = 15000; ax — приемник, 10000 — источник
mov cx,100
mov bx,15
sub cx,bx
Э
Т О И Н Т Е Р Е С Н О
Следует отметить, что ассемблер — максимально быстрый язык. Можно посчитать,
сколько раз за одну секунду процессор сможет сложить два любых числа от 0
до 65 535.
Каждая команда процессора выполняется определенное количество тактов. Когда го-
ворят, что тактовая частота процессора 100 МГц, то это значит, что за секунду прохо-
дит 100 миллионов тактов. Чтобы компьютер сложил два числа, ему нужно выполнить
следующие команды:
...
mov ax,2700
mov bx,15000
add ax,bx
...
В результате выполнения данных инструкций в регистре ax будет число 17 700, а в
регистре bx — 15 000. Команда add ax,bx выполняется за один такт на процессоре
80486. Получается, что компьютер 486 DX2-66 МГц за одну секунду сложит два любых
числа от 0 до 0FFFFh 66 миллионов (!) раз!
2.2.3. Оператор inc
Формат оператора
inc
представлен в табл. 2.7.
Таблица 2.7. Оператор
inc
Команда
Перевод
Назначение
Процессор
inc приемник
Increment
— инкремент
Увеличение на единицу
8086
Команда
inc
увеличивает на единицу содержимое приемника (регистра или
ячейки памяти). Она эквивалентна команде:
add источник, 1
только выполняется быстрее на старых компьютерах (до 80486) и занимает меньше
байтов (листинг 2.3).
Глава 2. Регистры процессора
21
Листинг 2.3. Примеры использования оператора inc
mov al,15
inc al ;теперь al = 16 (эквивалентна add al,1)
mov dh,39h
inc dh ;dh = 3Ah (эквивалентна add dh,1)
mov cl,4Fh
inc cl ;cl = 50h (эквивалентна add cl,1)
2.2.4. Оператор dec
Формат оператора
dec
представлен в табл. 2.8.
Таблица 2.8. Оператор
dec
Команда
Перевод
Назначение
Процессор
dec приемник
Decrement
— декремент
Уменьшение на единицу
8086
Команда
dec
уменьшает на единицу содержимое приемника (листинг 2.4). Она
эквивалентна команде:
sub источник, 1
Листинг 2.4. Примеры использования оператора dec
mov al,15
dec al ;теперь al = 14
mov dh,3Ah
dec dh ;dh = 39h
mov cl,50h
dec cl ;cl = 4Fh
2.3. Программа для практики
Рассмотрим одну небольшую программу, которая выводит на экран сообще-
ние и ждет, когда пользователь нажмет любую клавишу. После чего возвращается
в DOS.
Работать с клавиатурой позволяет прерывание BIOS (ПЗУ)
16h
, которое можно
вызывать даже до загрузки операционной системы, в то время как прерывания
20h
,
21h
и пр. доступны только после загрузки IO.SYS/MSDOS.SYS — определенной
части ОС MS-DOS.
Чтобы заставить программу ждать нажатия пользователем любой клавиши, сле-
дует вызвать функцию
10h
прерывания
16h
. Вот как это выглядит на практике:
mov ah,10h ;в ah всегда указывается номер функции
int 16h ;вызываем прерывание 16h — сервис работы с клавиатурой BIOS (ПЗУ)
Часть I. Знакомьтесь: ассемблер
22
После нажатия любой клавиши компьютер продолжит выполнять программу,
а регистр
ax
будет содержать код клавиши, которую нажал пользователь.
Следующая программа (\002\prog02.asm) выводит на экран сообщение и ждет
нажатия любой клавиши, что равнозначно команде
PAUSE
в BAT-файлах (лис-
тинг 2.5).
Листинг 2.5. Программа для практики
(01) CSEG segment
(02) org 100h
(03) Start:
(04)
(05) mov ah,9
(06) mov dx,offset String
(07) int 21h
(08)
(09) mov ah,10h
(10) int 16h
(11)
(12) int 20h
(13)
(14) String db 'Нажмите любую клавишу...$'
(15) CSEG ends
(16) end Start
Строки с номерами (01), (02) и (15) пока опускаем. В строках (05)—(07), как вы
уже знаете, производится вывод строки на экран. Затем (строки (09), (10)) про-
грамма ждет нажатия клавиши. И наконец, строка (12) завершает работу нашей
программы.
Мы уже изучили операторы
inc
,
dec
,
add
и
sub
. Вы можете поэкспериментиро-
вать (лучше в отладчике) с числами. Например, вот так:
...
mov ah,0Fh
inc ah
int 16h
...
Это позволит вам лучше запомнить новые операторы.
* * *
В главе 3 рассмотрим двоичную систему счисления, основы сегментации памяти
и сегментные регистры. Напишем интересную программу.
Глава 3
Сегментация памяти
в реальном режиме
В данной главе мы рассмотрим основополагающие принципы программирова-
ния на языке ассемблера. Необходимо тщательно разобраться в каждом предложе-
нии, уяснить двоичную систему счисления и понять принцип сегментации памяти
в реальном режиме. Мы также рассмотрим операторы ассемблера, которые не за-
трагивали в примерах из предыдущих глав. Сразу отмечу, что это одна из самых
сложных глав данной книги. Автор попытался объяснить все как можно проще,
избегая сложных определений и терминов. Если что-то не поняли — не пугайтесь!
Со временем все станет на свои места. Если вы полностью разберетесь с материа-
лом данной главы, то считайте, что базу ассемблера вы изучили. Начиная с главы 4,
будем изучать язык намного интенсивней.
Для того чтобы лучше понять сегментацию памяти, нам нужно воспользоваться
отладчиком. Лучше использовать в работе два отладчика: CodeView (CV.EXE) и
AFD Pro (AFD.EXE). Допустим, вы написали программу на ассемблере и назвали
ее prog03.asm. Сассемблировав, вы получили файл prog03.com. Тогда, чтобы запус-
тить программу под отладчиком CodeView/AFD, необходимо набрать в командной
строке MS-DOS следующее:
CV.EXE prog03.com
либо:
AFD.EXE prog03.com
Итак, вдохните глубже и — вперед!
3.1. Двоичная система счисления. Бит и байт
Рассмотрим, как в памяти компьютера хранятся данные. Вообще, как компью-
тер может хранить, например, слово "диск"? Главный принцип — намагничивание
и размагничивание одной дорожки (назовем это так). Одна микросхема памяти —
это, грубо говоря, огромное количество дорожек (примерно как на магнитофонной
кассете). Сейчас попробуем разобраться.
Предположим, что:
Ноль будет обозначаться как 0000 (четыре нуля),
Один 0001,
Два 0010 (т. е. правую единицу меняем на ноль,
а вторую устанавливаем в 1).
Часть I. Знакомьтесь: ассемблер
24
Далее так:
Три 0011
Четыре 0100
Пять 0101
Шесть 0110
Семь 0111
Восемь 1000
Девять 1001
и т. д.
"Нули" и "единицы" — это так называемые биты. Один бит, как вы уже замети-
ли, может иметь только два значения — 0 или 1, т. е. размагничена или намагниче-
на та или иная дорожка ("0" и "1" — это условное обозначение). Если внимательно
посмотреть, то можно обнаружить, что каждый следующий установленный бит,
начиная справа, увеличивает число в два раза: 0001 в нашем примере — один;
0010 — два; 0100 — четыре; 1000 — восемь и т. д. Это и есть двоичная форма
представления данных. Чтобы обозначить числа от 0 до 9, нам нужно четыре бита
(хоть они и не будут до конца использованы; можно было бы продолжить: де-
сять — 1010, одиннадцать — 1011, ..., пятнадцать — 1111).
Компьютер хранит данные в памяти именно так. Для обозначения какого-
нибудь символа (цифры, буквы, запятой, точки и др.) компьютер использует опре-
деленное количество бит. Компьютер "распознает" 256 (от 0 до 255) различных
символов по их коду. Этого достаточно, чтобы вместить все цифры (0—9), буквы
латинского алфавита (a—z, A—Z), русского (а—я, А—Я) и др. (см. приложение 3).
Для представления символа с максимально возможным кодом (255) нужно 8 бит.
Эти 8 бит называются байтом. Таким образом, один любой символ — это всегда
1 байт (табл. 3.1).
Таблица 3.1. Один байт с кодом символа "Z"
0
1
0
1
1
0
1
0
Р
Н
Р
Н
Н
Р
Н
Р
П
Р И МЕ Ч А Н И Е
Символы "Н" и "Р" в таблице обозначают "намагничено" или "размагничено" соответ-
ственно.
Можно элементарно проверить. Создайте в текстовом редакторе файл с любым
именем и напечатайте в нем один символ, например, "М", но не нажимайте клави-
шу <Enter>. Если вы посмотрите его размер, то файл будет равен 1 байту. Если ваш
редактор позволяет смотреть файлы в шестнадцатеричном формате, то вы сможете
узнать и код сохраненного символа. В данном случае — большая буква "М" имеет
код
4Dh
в шестнадцатеричной системе, которую мы уже знаем, или 1001101 в дво-
ичной. Таким образом, слово "диск" будет занимать 4 байта или 4 8 = 32 бита.
Как вы уже поняли, компьютер хранит в памяти не сами буквы (символы) этого
слова, а последовательность "единичек" и "ноликов".