- •Введение
- •1. Особенности персонального компьютера
- •1.1. Оперативная память
- •1.2. Регистры
- •1.3. Представление данных
- •1.4. Представление команд
- •2. Язык ассемблера. Начальные сведения
- •2.1. Лексемы
- •2.2. Предложения
- •2.3. Директивы определения данных
- •2.4. Директивы эквивалентности и присваивания
- •2.5. Выражения
- •3. Пересылки. Арифметические команды
- •3.1. Обозначения операторов команд
- •3.2. Команды пересылки
- •3.3. Команды сложения и вычитания
- •3.4. Команды умножения и деления
- •3.5. Изменение размера числа
- •3.6. Примеры
- •3.7. Лабораторная работа № 1
- •4. Переходы. Циклы
- •4.1. Безусловный переход
- •4.2. Команды сравнения и условного перехода
- •4.3. Команды управления циклом
- •4.4. Вспомогательные операции ввода-вывода
- •4.5. Массивы
- •4.6. Лабораторная работа № 2
- •5. Программные сегменты
- •5.1. Сегментирование адресов в пк
- •5.2. Программные сегменты
- •5.3. Начальная загрузка сегментных регистров
- •5.4. Структура программы
- •6. Стек
- •6.1. Стек и сегмент стека
- •6.2. Стековые команды
- •6.3. Приемы работы со стеком
- •7. Процедуры
- •7.1. Дальние переходы
- •7.2. Подпрограммы-процедуры
- •7.3. Передача параметров через регистры
- •7.4. Передача параметров через стек
- •7.5. Локальные данные процедур
- •7.6. Лабораторная работа № 3
- •8. Ввод и вывод данных
- •8.1. Реализация основных операций ввода-вывода
- •8.2. Операции ввода-вывода
- •8.3. Пример структуры программы
- •Заключение
- •Библиографический список
- •Оглавление
- •Учебное издание
- •394026 Воронеж, Московский просп., 14
3.5. Изменение размера числа
Рассмотрим такую задачу. Пусть к числу из регистра ВХ надо прибавить число из регистра AL: BX:=BX+AL. Здесь требуется сложить слово с байтом, но в ПК нет команды сложения слова с байтом. Поэтому, прежде всего надо сделать равными размеры этих чисел, а именно: надо расширить байт AL до слова, записав его, скажем, в регистр АХ, и только затем сложить числа из регистров АХ и ВХ. Возникает вопрос: как расширить байт AL до слова АХ с сохранением, конечно, величины числа?
Если число трактуется как беззнаковое, то делается это просто – надо слева к числу приписать нули: например, если AL=32=20h, то AX=0020h. Реализуется это записью 0 в левую часть регистра АХ, т. е. в регистр АН:
MOV АН,0 AL —> АХ (без знака)
Такое расширение называется расширением без знака.
Для чисел со знаком дело осложняется, т. к. надо учитывать знак числа. Если число неотрицательно, то для его расширения достаточно слева приписать нули. Но если число отрицательно, тогда слева надо приписывать двоичные единички (в шестнадцатеричной системе – две цифры F). К примеру, число -32 (-20h) в дополнительном коде как байт имеет вид 256-32 = 100h-20h = 0E0h, а как слово - 10000h-20h = 0FFE0h.
Итак, расширение знакового числа заключается в приписывании к нему слева нулей, если это число неотрицательно, или единичек, если число отрицательно. Такое расширение называется расширением со знаком.
Этому расширению можно дать и такую трактовку. Вспомним, что в дополнительном коде знакового числа самый левый бит является знаковым и что этот бит равен 0 для неотрицательных чисел и равен 1 для отрицательных. Поэтому можно сказать, что расширение со знаком заключается в дублировании слева знакового бита числа:
доп(+32) = 0010 0000b --> 0000 0000 0010 0000b
+
доп(-32) = 1110 0000b --> 1111 1111 1110 0000b
-
Для осуществления расширения со знаком в систему команд ПК введена специальная команда:
Расширение байта до слова (convert byte to word): CBW
У этой команды местонахождение операнда и результата фиксировано: операнд всегда берется из AL, а результат всегда записывается в АХ. Команда записывает в регистр АН число 00h или 0FFh в зависимости от знака числа из регистра AL:
00h при AL>=0
AH:=
0FFh при AL<0
Флаги эта команда не меняет.
Примеры:
MOV AL,32 ;AL=20h
CBW ;AX=0020h (число +32 как слово)
MOV AL,-32 ;AL=0E0h
CBW ;AX=0FFE0h (число -32 как слово)
Теперь вернемся к текущей задаче – к сложению BX:=BX+AL. В зависимости от того, как трактуются числа – как беззнаковые или как знаковые, она решается следующим образом:
; числа без знака:
MOV АН,0 ;AL->АХ (расширение без знака)
ADD BX,AX
; числа со знаком:
CBW ;АL -> АХ (расширение со знаком)
ADD BX, AX
Необходимость расширения байта до слова чаще всего возникает при делении байтов. Напомним, что в ПК можно делить слово на байт, но не байт на байт, поэтому, если необходимо разделить байт на байт, то прежде всего надо первый байт (делимое) расширить до слова. Например, присваивание AL:=AL div CH реализуется так:
;числа без знака:
MOV АН,0 ;AL -> АХ (без знака)
DIV CH ;AL:=AX div CH (AH:=AX mod CH)
;числа со знаком:
CBW ;AL -> АХ (со знаком)
IDIV СН ;Аl:=А div CH (AH:=AX mod CH)
Мы рассмотрели случай расширения байта до слова. Аналогично осуществляется расширение слова до двойного слова, необходимость в котором также возникает при делении. Обычно приходится расширять слово, находящееся в регистре АХ, до двойного слова, занимающего два регистра - DX и АХ, при условии, что в DX находится старшая часть числа, а в АХ - младшая:
АХ —> (DX,AX)
При этом условии расширение беззнакового числа АХ реализуется засылкой 0 в регистр DX:
MOV DX,0 ;АХ >(DX,AX) (без знака)
Если же число АХ рассматривается как знаковое, тогда для его расширения надо в регистр DX записать 0000h, если число неотрицательно, или 0FFFFh, если число отрицательно. Для этого в системе команд ПК есть специальная команда:
Расширение слова до двойного(convert word to double): CWD
Действие этой команды можно описать так:
0000h при AX>=0
DX:=
0FFFFh при AX<0
Примеры здесь аналогичны предыдущим.