Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kursova_Nykytiuk.docx
Скачиваний:
0
Добавлен:
18.09.2019
Размер:
56.36 Кб
Скачать

Команда порівняння

Команда порівняння CMP порівнює два числа, віднімаючи одне з іншого. Вона не записує результат, але прапори стану установлює відповідно до результату. Ця команда змінює тільки прапори. У програмі команда порівняння використовується так само, як і команда вирахування; однак команди порівняння з заемом не існує. Порівняння з підвищеною точністю вимагає ледве більше зусиль, чим порівняння чи байтів слів. Фактично в цих випадках багато простіше використовувати команду вирахування замість команди порівняння. На рис.П4.11 показане порівняння пари 32=бітових чисел у пам'яті з використанням регістра AX у якості області тимчасового збереження. Це порівняння визначає, яке з чисел більше. Програма в результаті свого виконання встановлює коди умови. Прапор переносу визначає, яке з чисел більше: якщо прапор дорівнює 1, число VALUE більше.

Програма перевіряє два 32=бітових числа на рівність. Програма зберігає молодший результат, а потім комбінує його зі старшим, і в такий спосіб з'ясовує еквівалентність результату нулю. Команда OR описана в наступному розділі, а тут істотно те, що вона комбінує два значення так, що остаточне значення дорівнює 0 тоді і тільки тоді, коли обоє вихідних значення рівні 0. Результат цієї підпрограми порівняння - значення прапора нуля; якщо він дорівнює 1, числа рівні.

Завдання 2.

В MASM написать программу решения задачи. Создать EXE и COM модули.

Даны натуральное число n, действительные числа a1, …, an. Вычислить

| a1* …* an|

Алгоритм вирішення завдання:

  1. Перемножаємо числа з а1 по аn.

  2. Знаходимо модуль добутку

  3. виводимо отриманий вирах на екран

COM модуль програми:

.model tiny ; модель памяти

.286

.code ; сегмент кода

org 100h ;значение программного счетчика org для сом файла

.startup ;начало программы

mov si,offset result1+len-2 ; копируем в регистр si начальное смещение выражения ;result1+len-2

mov di,offset result2+len-2 ; копируем в регистр di начальное смещение выражения ;result1+len-

mov dx,1

std ;установка флага направления df в 1

calc:mov bx,dx ; метка calc

mov cx,len-2 ;копируем в регистр сх значение

_mul:pusha ;помещает в стек регистры в следующем порядке: АХ, СХ, DX, ВХ, SP, ВР, SI и DI

_add:lodsb ;Копирует один байт из памяти по адресу DS:SI в регистр AL

add al,[di] ; помещает в регистр Al слово из ячейки памяти, селектор сегмента ;которой находится в DS, а смещение — в di

aaa ; Корректирует сумму чисел в AL

stosb ; Копирует регистр AL (STOSB) в память по адресу ES:DI

adc byte ptr [di],0 ;выполняет арифметическое сложение первого байта слова из ;ячейки памяти, селектор сегмента ;которой находится в DS, а смещение — в di, числа 0 и флага ;СF

loop _add ; Уменьшает регистр СХ на 1 и выполняет переход типа short на метку _add

popa ; загружает из стека DI, SI, BP, увеличивает SP на два, загружает ВХ,DX,CX,AX

dec b ; декремент опренданта b

jnz _mul; если флаг ZF = 0 происходит переход на метку _mul

inc dx ;инкремент dx

xchg si,di ; обмен местами значений в регистрах si и di

inc cx ; инкремент cx

pusha ;помещает в стек регистры в следующем порядке: АХ, СХ, DX, ВХ, SP, ВР, SI и DI

rep movsb ;выполняет команду movsb столько раз, сколько указано в регистре СХ уменьшая ;его при каждом выполнении команды на 1. movsb Копирует один байт из памяти по адресу DS:SI;в ;память по адресу ES:DI.

popa ;загружает из стека DI, SI, BP, увеличивает SP на два, загружает ВХ,DX,CX,AX

cmp dx,n ; сравнивает dx и n и устанавливает флаги CF, OF, SF, ZF, AF и PF

jnz calc ;если результат сравнения не ноль, то переход на calc

lea dx,[si-len+2] ; помещает в dx результат операции si-len+2

bcdtoasc:add byte ptr [si],'0';выполняет арифметическое сложение первого байта слова из ;ячейки памяти, селектор сегмента ;которой находится в DS, а смещение — в si, числа 0 и флага ;СF

dec si ; декремент si

loop bcdtoasc; Уменьшает регистр СХ на 1 и выполняет переход типа short на метку bcdtoasc

mov ah,9; номер функции дос - в ah

int 21h ;вызов системной функции DOS

xor ax,ax ; обнуление регистра ах

int 16h ; прерывание биос для ожидания ввода с клавиатуры

ret ;завершение СОМ-программы

n=29 ; количество чисел, которые будут умножаться

result1 db 30 dup(0),1,'$'; создает массив из байтов (каждый байт - 0,1 и символ конца ;строки ), на первый из которых указывает переменная result1

result2 db 30 dup(0),1,'$';аналогично

len = $-result2 ;от значения текущего счетчика программы отнять result2

end

; подсчет модуля можно мыло бы осуществить следущим образом:

;label10: neg ax ; изменить знак регистра ax

; js label10 ; если знаковый флаг SF установлен в 1 , то переходим на метку

;но произведение чисел от a1 до an по сути являет собой факториал n!, который

;всегда будет положительным числом, так что необходимость в подсчете модуля отпадает

EXE модуль програми:

.code ; сегмент кода

.stack 100h

mov ax,DGROUP

mov ds,ax

.startup ;начало программы

mov si,offset result1+len-2 ; копируем в регистр si начальное смещение выражения ;result1+len-2

mov di,offset result2+len-2 ; копируем в регистр di начальное смещение выражения ;result1+len-

mov dx,1

std ;установка флага направления df в 1

calc:mov bx,dx ; метка calc

mov cx,len-2 ;копируем в регистр сх значение

_mul:pusha ;помещает в стек регистры в следующем порядке: АХ, СХ, DX, ВХ, SP, ВР, SI и DI

_add:lodsb ;Копирует один байт из памяти по адресу DS:SI в регистр AL

add al,[di] ; помещает в регистр Al слово из ячейки памяти, селектор сегмента ;которой находится в DS, а смещение — в di

aaa ; Корректирует сумму чисел в AL

stosb ; Копирует регистр AL (STOSB) в память по адресу ES:DI

adc byte ptr [di],0 ;выполняет арифметическое сложение первого байта слова из ;ячейки памяти, селектор сегмента ;которой находится в DS, а смещение — в di, числа 0 и флага ;СF

loop _add ; Уменьшает регистр СХ на 1 и выполняет переход типа short на метку _add

popa ; загружает из стека DI, SI, BP, увеличивает SP на два, загружает ВХ,DX,CX,AX

; dec b ; декремент опренданта b

jnz _mul; если флаг ZF = 0 происходит переход на метку _mul

inc dx ;инкремент dx

xchg si,di ; обмен местами значений в регистрах si и di

inc cx ; инкремент cx

pusha ;помещает в стек регистры в следующем порядке: АХ, СХ, DX, ВХ, SP, ВР, SI и DI

rep movsb ;выполняет команду movsb столько раз, сколько указано в регистре СХ уменьшая ;его при каждом выполнении команды на 1. movsb Копирует один байт из памяти по адресу DS:SI;в ;память по адресу ES:DI.

popa ;загружает из стека DI, SI, BP, увеличивает SP на два, загружает ВХ,DX,CX,AX

cmp dx,n ; сравнивает dx и n и устанавливает флаги CF, OF, SF, ZF, AF и PF

jnz calc ;если результат сравнения не ноль, то переход на calc

lea dx,[si-len+2] ; помещает в dx результат операции si-len+2

bcdtoasc:add byte ptr [si],'0';выполняет арифметическое сложение первого байта слова из ;ячейки памяти, селектор сегмента ;которой находится в DS, а смещение — в si, числа 0 и флага ;СF

dec si ; декремент si

loop bcdtoasc; Уменьшает регистр СХ на 1 и выполняет переход типа short на метку bcdtoasc

mov ah,9; номер функции дос - в ah

int 21h ;вызов системной функции DOS

xor ax,ax ; обнуление регистра ах

int 16h ; прерывание биос для ожидания ввода с клавиатуры

mov ax,4C00h

int 21h

n=29 ; количество чисел, которые будут умножаться

result1 db 30 dup(0),1,'$'; создает массив из байтов (каждый байт - 0,1 и символ конца ;строки ), на первый из которых указывает переменная result1

result2 db 30 dup(0),1,'$';аналогично

len = $-result2 ;от значения текущего счетчика программы отнять result2

end

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]