Материал: 1328

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Последнее, в свою очередь, может произойти:

при делении делимого величиной в слово со знаком на делитель величиной в байт со знаком, причем значение делимого более чем в 128 раз больше значения делителя (т.к. частное не должно находиться вне диапазона от –128 до +127);

при делении делимого величиной в двойное слово со знаком на делитель величиной в слово со знаком, причем значение делимого более чем в 32 768 раз больше значения делителя (т.к. частное не должно находиться вне диапазона от –32 768 до +32 767).

Вспомогательные команды для целочисленных операций – рассматриваются ниже.

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

1.Общие сведенья об арифметических операциях над числами со знаком.

2.Сложение двоичных чисел со знаком. В каких случаях происходит переполнение и получается неправильный результат.

3.Вычитание двоичных чисел со знаком. Применение дополнительного кода. Вычитание положительного числа из отрицательного числа.

4.Умножение чисел со знаком.

5.Деление чисел со знаком. Причины возникновения ситуации «деление на ноль».

46

6. ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ

6.1. Включаемые файлы

Часто оказывается желательным включить один и тот же блок исходного кода ассемблера в несколько исходных модулей. В этом случае чрезвычайно удобной оказывается директива include.

Когда ассемблер встречает директиву include (включить), текст включаемого файла включается в ассемблирование текущего исходного модуля ассемблера. Например, если файл mainprog.asm содержит:

. . .

.code mov ax,1

include incprog.asm push ax

. . .

афайл incprog.asm содержит: mov bx,5

add ax,bx

то результат ассемблирования файла mainprog.asm будет в точности эквивалентен ассемблированию кода:

. . .

.code mov ax,1 mov bx,5 add ax,bx push ax

. . .

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

6.2. Команды преобразования типов

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

47

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

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

cbw (convert byte to word) - команда преобразования байта (в регистре al) в слово (в регистре ax) путем распространения значения старшего бита al на все биты регистра ah;

cwd (convert word to double) - команда преобразования слова (в регистре ax) в двойное слово (в регистрах dx:ax) путем распространения значения старшего бита ax на все биты регистра dx.

Например, сложение байта и слова, если это числа со знаком, может быть реализовано следующим образом:

.data

 

b1 db ?

 

w1 dw ?

 

.code

 

main proc far

 

. . .

 

mov al,b1

;al:=b1

cbw

;ax:=b1

add ax,w1

;ax:=b1+w1

; проверка флага cf. Если cf=1, то ошибка

. . .

Другой пример, сложение двойного слова и слова, если это числа со знаком:

.data

 

d1 dd ?

 

w1 dw ?

 

.code

 

main proc far

 

. . .

 

mov al,w1

;ax:=w1

cwd

;(dx:ax) :=w1

add ax,word ptr d1

 

adc dx,word ptr d1+2

; (dx:ax):=d1+w1

 

48

; проверка флага cf. Если cf=1, то ошибка

. . .

6.3. Отрицание с дополнением до двух

Формат команды: neg <операнд>

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

<операнд>= 0 – <операнд> Команду neg операнд можно применять:

для смены знака;

для выполнения вычитания из константы.

Т.к. команды sub и sbb не позволяют вычесть что-либо из константы, то данную операцию можно выполнить с помощью двух

команд:

 

neg ax

;смена знака (ax)

. . .

 

add ax,340

;фактически вычитание: ax:=340-ax

6.4.Арифметические и логические операции

вмикропроцессорах МП8086 и МП80386

6.4.1.Арифметические операции в микропроцессорах МП8086 и МП80386 показаны для беззнаковых чисел на примерах вычисления по формулам (приложение 5):

d1+w1+b1+d2+w2+b2

d1-w1-b1-d2-w2-b2

b1*b2*w1*d1

6.4.2.Логические поразрядные операции в микропроцессорах МП8086 и МП80386 показаны на примерах вычисления по формулам (приложение 5):

d1 or w1 or b1 or d2 or w2 or b2

d1 and w1 and b1 and d2 and w2 and b2

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

1.Включаемые файлы. Директива include.

2.Команды преобразования типов для знаковых данных (cbw, cwd,

cdq).

3.Отрицание с дополнением до двух (neg).

49

7. ТИПИЧНЫЕ ОШИБКИ ПРИ ВЫПОЛНЕНИИ РАБОТЫ

7.1.Перечень часто встречающихся ошибок

7.1.1.Перечень ошибок тот же, что и в первых двух работах (см.

уч.пос., ч.1 и 2):

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

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

- потеря содержимого регистра при умножении; - не подготовлены регистры при делении;

- неправильное использование регистра после деления; - потеря содержимого регистра при делении;

- неправильное использование регистров в командах cbw и cwd;

- применение команд преобразования cbw и cwd к беззнаковым данным;

- изменение отдельными инструкциями флага переноса; - программист долго не использует состояние флагов; - ошибки при использовании регистров; - выход из диапазона адресов;

- программист забывает об инструкции ret; - генерация неверного типа возврата;

- ошибки при использовании условных переходов; - перепутаны операнды в памяти и непосредственные операнды; - границы сегментов.

7.1.2Типичные ошибки, которые допускаются при программировании на ассемблере, и рекомендации, как можно их избежать, приведены ниже. Источники данной информации: [1; 4; 5; 6].

7.2.Открытая процедура или открытый сегмент

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

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

50

Источник: https://studfile.net/preview/16407385/