И числа со знаком, и беззнаковые числа состоят из последова-тельности двоичных цифр. Ответственность за различие этих двух видов чисел возлагается на программиста, который пишет программу на Ассемблере (то есть на вас), а не на процессор 8086. Например, значение 0FFFFh может представлять собой либо 65535, либо -1, в зависимости от того, как ваша программа его интерпретирует.
Откуда вы знаете, что 0FFFFh — это -1? Прибавьте к нему 1:
mov ax,0ffffh
add ax,1
.и вы обнаружите, что результат будет равен 0. Как раз такой ре-зультат должен получиться при сложении -1 и 1.
Одна и та же инструкция ADD будет работать одинаково хорошо, независимо от того, представляют ли собой операнды значения со знаком или беззнаковые значения. Предположим, например, что вы вычли из 0FFFFh значение -1 следующим образом:
.mov ax,offffh
sub ax,1
.
Результат при этом был бы равен 0FFFEh, что представляет со-бой 65534 (беззнаковое число) или -2 (число со знаком).
Если это кажется непонятным, прочитайте одну из книг, реко-мендуемых в конце данного руководства (или одну из книг по Ас-семблеру, изданных в СССР, например книгу Бредли). Это позволит вам больше узнать об арифметике с дополнением до двух — средстве, с помощью которого процессор 8086 обрабатывает числа со знаком. К сожалению, мы не располагаем здесь местом, чтобы подробно расска-зать об арифметике значений со знаком, хотя для программиста это представляет собой одну из важных тем, которую нужно хорошо пони-мать. Пока же запомните, что инструкции ADD, SUB, ADC и SBB рабо-тают одинаково хорошо как с беззнаковыми значениями, так и со значениями со знаком, поэтому для таких операций не требуется специальных инструкций сложения или сочетания. Знак имеет значе-ние в операциях умножения или деления (как вы увидите далее), а также при преобразовании размеров данных.
TASM2 #1-5/Док = 204 =
Преобразование размеров данных
Иногда бывает необходимо преобразовать слова в байты или на-оборот. При этом, как и в других действиях, значения могут быть со знаком или без знака.
Давайте сначала рассмотрим преобразование слова в байт. Это довольно просто: нужно только избавиться от старшего байта слова.
Например:
mov ax,5
mov bl,al
Здесь значение 5 размером в слово в регистре AX преобразует-ся в байтовое значение 5 в регистре BL. Конечно, вы должны быть уверены, что преобразуемое вами значение поместится в байте. По-пытка преобразовать в байт значение 100h с помощью инструкций:
.mov dx,100h
mov al,dl
.была бы безуспешной, так как в регистр AL был бы записан только младший (нулевой) байт.
Преобразование беззнакового байтового значения в слово зак-лючается просто в обнулении старшего байта слова. Например, инс-трукции:
.mov cl,12
mov al,cl
mov ah,0
.преобразуют беззнаковое значение 12 в регистре CL в значение 12 размером в слово в регистре AX.
Преобразование в слово байтового значения со знаком несколь-ко более сложно, поэтому в процессоре 8086 для выполнения этой задачи предусмотрена специальная инструкция CBW. Инструкция CBW преобразует байтовое значение со знаком в регистре AL в значение со знаком размером в слово в регистре AX. В следующем фрагменте программы байтовое значение со знаком -1 в регистре DH преобразу-ется в значение со знаком размером в слово в регистре DX (-1):
mov dh,-1
mov al,dh
cbw
mov dx,ax
В наборе инструкций процессора 8086 для преобразования слова со знаком в регистре AX в двойное слово со знаком в регистрах DX:
AX (старшее слово содержится в регистре AX) предусмотрена специ-альная инструкция CWD. Следующие инструкции преобразуют значение со знаком +10000 (размером в слово), содержащееся в регистре AX, в значение со знаком +10000 (размером в двойное слово), содержа-щееся в паре регистров DX:AX:
mov ax,10000
cwd
Беззнаковые значения размером в слово можно преобразовать в беззнаковые значения размером в двойное слово путем обнуления старшего слова значения.