Регистры процессора
В данной главе рассматриваются регистры процессоров работа с ними и примеры команд.Регистр процессора, как мы уже рассматривали раньше, - это, просто говоря, специально отведённая память для временного хранения каких-то данных, переменная.
Процессоры 8086 - 80186 имеют 14 регистров. В прошлой главе мы встретили два из них: AH и DX. В Таблицах № 1, 2 и 3 приведены списки всех регистров, кроме IP и регистра флагов, которые со временем будут рассматриваться отдельно:
Таблица № 1. Регистры данных
AX |
BX |
CX |
DX |
||||
AH |
AL |
BH |
BL |
CH |
CL |
DH |
DL |
Все регистры процессора можно разделить на регистры данных и сегментные регистры.
Регистры данных (Таблица № 1)
Эти регистры процессора могут использоваться программистом по своему усмотрению (за исключением
некоторых случаев). В них можно хранить любые данные (числа, адреса и пр.). В
верхнем ряду
AX (Accumulator register - аккумулятор). Применяется для хранения
промежуточных данных. В некоторых командах использование этого регистра
обязательно
BX (Base register - база). Применяется для хранения базового адреса
некоторого объекта в памяти
CX (Count register - счетчик). Применяется в командах, производящих
некоторые повторяющиеся действия.
DX (Data register - регистр данных). Так же, как и регистр AX, он хранит
промежуточные данные. В некоторых командах его использование обязательно; для
некоторых команд это происходит неявно
Эти шестнадцатиразрядные регистры могут хранить числа от 0 до 65.535 (от 0h до
FFFFh в шестнадцатеричной системе (вспоминаем прошлую главу)). Под ними идет
ряд восьмиразрядных регистров (AH, AL, BH, BL, CH, CL, DH, DL), которые могут
хранить максимальное число 255 (FFh). Это половинки (старшая или младшая)
шестнадцатиразрядных регистров.
Например:
Мы уже знаем оператор MOV, который предназначен для загрузки числа в регистр. Чтобы присвоить, к примеру, регистру AL число 35h, нам необходимо записать так:
mov al,35h
а регистру AX число 346Ah - так:
mov ax,346Ah
Если мы попытаемся загрузить большее число, чем может содержать регистр, то, при ассемблировании программы произойдет ошибка.
Например, следующие записи будут ошибочны:
mov ah,123h максимум FFh
mov bx,12345h максимум FFFFh
mov dl,100h максимум FFh
Здесь надо отметить, что если шестнадцатеричное число начинается не с цифры (напр.: 12h), а с буквы (A-F) (напр.: С5h), то перед таким числом ставится нуль: 0C5h. Это необходимо для того, чтобы программа-ассемблер могла отличить где шестнадцатеричное число, а где метка. Ниже мы рассмотрим это на примере.
Допустим, мы выполнили команду mov ax,1234h. В этом случае в регистре AH будет находится число 12h, а в регистре AL - 34h. Т.е. AL, BL, CL, DL - это младшие (Low), а AH, BH, CH, DH - старшие (High) половинки шестнадцатиразрядных регистров (см. Таблицу № 4).
Таблица № 4. Результаты выполнения различных команд |
|
Команда |
Результат |
mov ax,1234h |
AX = 1234h, AH = 12h, AL = 34h |
mov bx,5678h |
BX = 5678h, BH = 56h, BL = 78h |
mov cx,9ABCh |
CX = 9ABCh, CH = 9Ah, CL = 0BCh |
mov dx,0DEF0h |
DX = 0DEF0h, DH = 0DEh, DL = 0F0h |
Рассмотрим еще два оператора: ADD и SUB. Оператор ADD имеет следующий формат (в последствии мы всегда будем оформлять новые команды в такие таблицы):
Команда |
Перевод |
Назначение |
Процессор |
ADD приемник, источник |
ADDition - сложение |
Сложение |
8086 |
В столбце Команда будет описываться новая команда и ее применение. В столбце Назначение - что выполняет или для чего служит данная команда, а в столбце Процессор - модель (тип) процессора с которого она поддерживается. Перевод - с какого английского слова образован оператор и его перевод. В данном примере - это 8086 процессор, но работать команда будет, естественно и на последующих, более современных процессорах (80286, 80386 и т.д.).
Команда ADD производит сложение двух чисел.
Примеры:
mov al,10 ; загружаем в регистр AL число 10
add al,15 ; AL = 25; AL - приемник, 15 - источник
mov ax,25000 ; загружаем в регистр AX число 25000
add ax,10000 ; AX = 35000; AX - приемник, 10000 - источник
mov cx,200 ; загружаем в регистр CX число 200
mov bx,760 ; а в регистр BX - 760
add cx,bx ; CX = 960, BX = 760 (BX не меняется), CX - приемник, BX - источник
Команда |
Перевод |
Назначение |
Процессор |
SUB приемник, источник |
SUBtraction - вычитание |
Вычитание |
8086 |
Оператор Ассемблера SUB производит вычитание двух чисел
Примеры:
mov al,10 ; запись 10 в регистр процессора al
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 ; CX = 85, BX = 15 (BX не меняется!), CX - приемник, BX - источник
Это интересно
Следует отметить, что Ассемблер максимально быстрый язык. Можно посчитать
сколько раз за одну секунду процессор сможет сложить два любых числа от 0 до
65535.
Каждая команда процессора выполняется определённое количество тактов. Когда
говорят, что тактовая частота процессора 100Mhz, то это значит, что за секунду
проходит 100 миллионов тактов.
Чтобы сложить два числа в Ассемблере нужно выполнить следующие команды:
mov ax,2700
mov bx,15000
add ax,bx
Как мы видим используется только 2 регистра процессора.
В результате выполнения данных инструкций, в регистре AX будет число 17700, а в регистре BX - 15000. Команда add ax,bx выполняется за один такт на процессоре 80486. Получается, что компьютер 486 DX2-66Mhz за одну секунду сложит два любых числа (от 0 до 0FFFFh) 66 миллионов (!) раз! А еще называют «четверку» медленной!..
Регистры-указатели (Таблица № 2)
Таблица № 2. Регистры-указатели
SI |
DI |
BP |
SP |
Регистры SI (Source Index register - индекс источника) и DI (Destination Index register - индекс приемника) используются в строковых операциях. Регистры BP и SP необходимы при работе со стеком. Мы их будем подробно рассматривать в последующих главах.
Сегментные регистры (Таблица № 3)
Таблица № 3. Сегментные регистры
CS |
DS |
ES |
SS |
Сегментные регистры необходимы для обращения к тому или иному сегменту памяти (например, видеобуферу). Сегментация памяти довольно сложная и объемная тема, которую также будем рассматривать в последующих главах
Давайте изучим еще несколько команд в данной главе:
Команда |
Перевод |
Назначение |
Процессор |
INC приемник |
INCrement - инкремент |
Увеличение на единицу |
8086 |
Команда INC увеличивает на единицу регистр. Она эквивалентна команде: ADD источник, 1 только выполняется быстрее на старых компьютерах (до 80486) и занимает меньше байт.
Примеры:
mov al,15 ; запись 15 в регистр процессора al
inc al ; теперь AL = 16 (эквивалентна add al,1)
mov dh,39h ; запись 39h в регистр процессора dh
inc dh ; DH = 3Ah (эквивалентна add dh,1)
mov cl,4Fh
inc cl ; CL = 50h (эквивалентна add cl,1)Программка для практики
Сегодня рассмотрим одну небольшую программку, которая выводит на экран сообщение, и ждет, когда пользователь нажмет любую клавишу. После чего возвращается в DOS.
Управлять клавиатурой позволяет прерывание 16h. Это прерывание BIOS (ПЗУ), а не MS-DOS (как 21h). Его можно вызывать даже до загрузки операционной системы, в то время, как прерывание 21h доступно только после загрузки IO.SYS / MSDOS.SYS (т.е. определенной части ОС MS-DOS).
Чтобы остановить программу до нажатия любой клавиши следует вызвать функцию 10h прерывания 16h. Вот как это выглядит (после символов ";" идет комментарий):
mov ah,10h ; в AH всегда указывается номер функции
int 16h ; вызываем прерывание 16h - сервис работы с клавиатурой BIOS (ПЗУ)
После нажатия на любую клавишу, компьютер продолжит выполнять программу, а регистр AX будет содержать код клавиши, которую нажал пользователь.
Следующая программа выводит на экран сообщение и ждет нажатия любой клавиши (равнозначна команде "pause" в *.bat файлах):
(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, ADD и SUB. Можно
поэкспериментировать с вызовом прерывания. Например, так:
mov ah,0Fh
inc ah
int 16h
Это позволит Вам лучше запомнить новые операторы.
В следующей главе рассмотрим двоичную систему счисления, основы сегментации памяти и сегментные регистры. Напишем интересную программку.