Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

1011

.pdf
Скачиваний:
4
Добавлен:
07.01.2021
Размер:
816.97 Кб
Скачать

cmp ax,30h ; сравнение и zf:=1, если операнды равны, т.е. ax=30h (т.е. 0011 0000),

;и sf:=1, если ax<30h

jb error_b ; переход на error_b, если sf=1, т.е. если ax <30h

cmp ax,39h ; сравнение и zf:=0, если операнды не равны (ax<>39h, т.е. 0011 1001),

;и sf:=0, если ax>39h

ja error_b ; переход на error_b, если sf=0 и zf=0, т.е. если ax >39h

and al,0fh ; зануление четырех старших битов в байте (т.е. в регистре al) and bl,0fh

mov dx,0 mov ax,0 abd1: cmp bl,0 jz abd2

add ax,word ptr fml adc dx,word ptr fml+2 dec bl

jmp abd1

abd2: add word ptr promd,ax adc word ptr promd+2,dx mov bl,9

mov dx,word ptr fml+2 mov ax, word ptr fml

abd3: cmp bl,0 jz abd4

add word ptr fml,ax adc word ptr fml+2,dx dec bl

jmp abd3 abd4:

dec si

loop met1_d

mov dx,word ptr promd+2 mov ax,word ptr promd

jmp end_error_d

 

error_d:

 

mov ah,09h

; вывод на экран сообщения

lea dx,msg_err1

; "Ошибка#1: ошибка ввода

int 21h

 

mov osh_v,1

; osh_v := 1

end_error_d:

 

ret

; возврат в DOS

ASCII_bin_d endp

; конец процедуры

; Процедура в данном примере не используется

COMMENT @

cursor proc ;процедура перевода курсора на след. строку

@

codesg ends ; ends – директива, показывающая конец сегмента end main ; конец программы

==================================================================

101

Пример 1.5

;lab1pr5.asm ред. 17_12_05

;РАЗРАБОТАЛ МИШУРИН А.О., СТУДЕНТ ГРУППЫ 11БИ, ИЮЛЬ 2003 ГОДА. ;Программа (работает с МП 8086) осуществляет перевод из bin (двоичное число) в ASCII

;(значения берутся из ячеек памяти) + вывод на экран результата. ;Компиляция: tasm.exe lab1pr5.asm

;tlink.exe lab1pr5.obj

;-сегмент стека---------------------------------

stacksg segment para stack 'Stack' db 128 dup(?)

stacksg ends

;-сегмент данных----------------------------------

datasg segment para 'Data' msg_b1 db "b1=",0dh,0ah,"$" msg_w1 db "w1=",0dh,0ah,"$" msg_d1 db "d1=",0dh,0ah,"$"

msg_err1 db "Ошибка#1: ошибка ввода!", 0dh,0ah,"$"

msg_e db "Для выхода нажмите любую клавишу!", 0dh,0ah,"$"

ascval db "000000000000",0dh,0ah,"$" ; 12 нулей (под дв. слово в символьном виде) perevod_cursora db 0dh,0ah,"$"

COMMENT @ vvod_b label byte maxlen_b db 4 fact_b db 0 simv_b db "0000" vvod_w label byte maxlen_w db 6 fact_w db 0

simv_w db "000000" vvod_d label byte maxlen_d db 11 fact_d db 0

simv_d db "00000000000"

@

 

b1 db 255

 

w1 dw 65535

 

d1 dd 2147483647

 

COMMENT @

 

prom dw 0

 

promd dd 0

 

fml dd 0

 

osh_v db 0

 

@

 

rezult dq 0

 

kol dq 0

 

datasg ends

; конец сегмента данных

 

102

;- сегмент кода----------------------------------

 

 

codesg segment para 'Code'

; para – параграф (сегмент должен начинаться с

;

адреса, кратного шестнадцати, т.е. на границе параграфа)

main proc far

; начало процедуры (main – имя процедуры; far – дальняя)

assume cs:codesg,ds:datasg,ss:stacksg

; директива, устанавливающая соответствие

;сегментных регистров (cs, ds, ss) сегментам (ее обычный вид для EXE-программы)

;следующие строки должны быть в любой EXE-программе:

push ds

 

; сохранение содержимого регистра ds в стеке (для возврата в DOS)

xor ax,ax

 

; ax:=0

 

push ax

 

; ячейка в стеке для MS-DOS (требование – д.б. равна нулю)

mov ax,datasg

; инициализация регистра ds (заносится адрес

mov ds,ax

 

; начала сегмента данных)

mov ax,0600h

; ah=06(прокрутка), al=00(весь экран)

mov bh,07

 

; нормальный атрибут (черно-белый)

mov cx,0000

; очистка экрана | верхняя левая позиция

mov dx,314fh

;

нижняя правая позиция

int 10h

 

; передача управления в BIOS

mov ah,02 ;\

 

| установка курсора

mov bh,00 ; \

 

| экран 0

mov dh,00 ; управление курсором | строка 00

mov dl,00

; /

 

| столбец 00

int 10h

;/

 

| передача упр. в BIOS

snova:

 

 

 

mov ah,09h

; функция вывода на экран сообщения

lea dx,msg_b1

;

"b1="

int 21h

 

; передача управления в DOS

xor ax,ax mov al,b1

mov word ptr rezult,ax

call bin_ASCII

;вызов процедуры перевода из bin (двоичное) в ASCII

;

результат – число в кодах ASCII – в ячейке ascval

mov ah,09h

; функция вывода на экран сообщения

lea dx,ascval

; число 255, т.е. значение b1 (в кодах ASCII)

int 21h

 

mov ah,09h

; функция вывода на экран

lea dx,msg_w1

; "w1="

int 21h

 

mov ax,w1

 

mov word ptr rezult,ax

 

call bin_ASCII

;вызов процедуры перевода из bin (двоичное) в ASCII

;

результат – число в кодах ASCII – в ячейке ascval

mov ah,09h

; вывод на экран содержимого ячейки ascval

lea dx,ascval

; т.е. значение w1, равное 65535 (в кодах ASCII)

int 21h

 

mov ah,09h

; вывод на экран сообщения

lea dx,msg_d1

; "d1="

int 21h

 

mov ax,word ptr d1

; мл.слово d1 в регистр ax

 

103

mov dx,word ptr d1+2

 

; ст.слово d1 в регистр dx

mov word ptr rezult,ax

 

 

mov word ptr rezult+2,dx

; rezult:= d1

call bin_ASCII

 

;вызов процедуры перевода из bin (двоичное) в ASCII

;

 

 

результат – число в кодах ASCII – в ячейке ascval

mov ah,09h

 

; вывод на экран сообщения

lea dx,ascval

 

; число 2 147 483 647, т.е. значение d1 (в кодах ASCII)

int 21h

 

 

 

mov ah,02 ;\

| установка курсора

mov bh,00 ; \

| экран 0

mov dh,24 ; управление курсором | строка 23

mov dl,00

; /

| столбец 00

int 10h

;/

| передача упр. в BIOS

mov ah,09h

; вывод на экран сообщения

lea dx,msg_e

; "Для выхода нажмите любую клавишу!"

int 21h

 

 

 

mov ah,0

 

;-ожидание нажатия клавиши

int 16h

 

 

 

ret

 

;возврат в DOS

main endp

 

 

 

;-процедуры

-----------------------------

 

 

; Процедуры в данном примере не используются

COMMENT @

 

ASCII_bin_b proc

;процедура перевода из ASCII в bin для байта

(Вход: список параметров vvod_b должен быть заполнен; выход: al=число в bin)

ASCII_bin_w proc

;процедура перевода из ASCII в bin для слова

(Вход: список параметров vvod_w должен быть заполнен; выход: ax=число в bin)

ASCII_bin_d proc

;процедура перевода из ASCII в bin для дв. слова для МП 8086

(Вход: список параметров vvod_d должен быть заполнен; выход: dx:ax=число в bin)

@

 

bin_ASCII proc

;процедура перевода из bin (двоичное) в ASCII

;( Вход: rezult=число двоичное);

;выход: ascval= число в ASCII)

call clrascval ;вызов процедуры очистки строковой переменной ascval

lea si,ascval+11 ; изменено на 11 (в связи с изменением кол-ва символов в ascval)

m1:

 

cmp word ptr rezult+6,0

;сравнение слова с нулем и zf:=1, если операнды равны

jnz m2

; переход на m2, если zf=0

cmp word ptr rezult+4,0

; rezult+4 равен нулю? и zf:=1, если операнды равны

jnz m2

; переход на m2, если zf=0

cmp word ptr rezult+2,0

 

jnz m2

 

cmp word ptr rezult,10

; слово rezult равно десяти? и zf:=1, если равно

;

cf:=0, если слово rezult больше или равно десяти

jnb m2

; переход на m2, если cf=0

mov ax,word ptr rezult

 

or al,30h

 

 

104

mov [si],al

 

dec si

 

jmp m3

 

m2:

 

sub word ptr rezult,10

 

sbb word ptr rezult+2,0

 

sbb word ptr rezult+4,0

 

sbb word ptr rezult+6,0

; result := result – 10

add word ptr kol,1

 

adc word ptr kol+2,0

 

adc word ptr kol+4,0

 

adc word ptr kol+6,0

; kol := kol + 1

jmp m1

 

m3:

 

cmp word ptr kol+6,0

 

jne m4

 

cmp word ptr kol+4,0

 

jne m4

 

cmp word ptr kol+2,0

 

jne m4

 

cmp word ptr kol,0

 

jne m4

 

ret

 

m4:

 

mov ax,word ptr kol

 

mov word ptr rezult,ax

 

mov ax,word ptr kol+2

 

mov word ptr rezult+2,ax

 

mov ax,word ptr kol+4

 

mov word ptr rezult+4,ax

 

mov ax,word ptr kol+6

 

mov word ptr rezult+6,ax

; result (учетверенное слово) := kol (учетверенное слово)

mov word ptr kol,0

 

mov word ptr kol+2,0

 

mov word ptr kol+4,0

 

mov word ptr kol+6,0

; kol (учетверенное слово) := 0

jmp m1

 

bin_ASCII endp

; конец процедуры

clrascval proc

; процедура ‘ближняя’, т.е. типа near (по умолчанию)

mov cx,12 ; изменено на 12 (в связи с изменением к-ва символов в ascval); было 20 mov si,11 ; изменено на 11 (в связи с изменением к-ва символов в ascval); было 19

clr1: and ascval [si],30h dec si

105

loop clr1 ret

clrascval endp ; конец процедуры

cursor proc ;процедура перевода курсора на след. строку mov ah,09

lea dx,perevod_cursora int 21h

ret cursor endp

codesg ends ; ends – директива, показывающая конец сегмента end main ; конец программы

===================================================================

Пример 1.6

;lab1pr6.asm ред. 17_12_05

;РАЗРАБОТАЛ МИШУРИН А.О., СТУДЕНТ ГРУППЫ 11БИ, ИЮЛЬ 2003 ГОДА. ;Программа (МП 8086) вычисляет по формулам: b1+b2; w1+w2; w1-b1; d1+d2

;Компиляция: tasm.exe lab1pr6.asm

;tlink.exe lab1pr6.obj

;-сегмент стека---------------------------------

stacksg segment para stack 'Stack' db 1024 dup(?)

stacksg ends

;-сегмент данных-------------------------------

datasg segment para 'Data' msg_b1 db "b1=",0dh,0ah,"$" msg_w1 db "w1=",0dh,0ah,"$" msg_d1 db "d1=",0dh,0ah,"$"

msg_b1b2 db "b1+b2=",0dh,0ah,"$" msg_w1w2 db "w1+w2=",0dh,0ah,"$" msg_d1d2 db "d1+d2=",0dh,0ah,"$" msgd1_d3 db "d1-d3=",0dh,0ah,"$" msg_w1b1 db "w1-b1=",0dh,0ah,"$"

msg_e db "Для выхода нажмите любую клавишу!", 0dh,0ah,"$" msg_err1 db "Ошибка#1: ошибка ввода!", 0dh,0ah,"$"

ascval db "000000000000",0dh,0ah,"$" ; 12 нулей (под дв. слово в символьном виде) perevod_cursora db 0dh,0ah,"$"

; сюда вставляются списки параметров (из файла vvod_bwd.asm)

include vvod_bwd.asm ; include – директива, вставляющая в текст программы текст ; файла (в данном ; случае вставляется текст файла vvod_bwd.asm ) b1 db 255

b2 db 10

w1 dw 65535

w2 dw 1000

d1 dd 2147483647

d2 dd 3000000000

d3 dd 147483647 prom dw 0 promd dd 0

106

fml dd 0

 

osh_v db 0

 

rezult dq 0

 

kol dq 0

 

datasg ends

; конец сегмента данных

;- сегмент кода----------------------------------

 

codesg segment para 'Code' ; para – параграф (сегмент должен начинаться с

;

адреса, кратного шестнадцати, т.е. на границе параграфа)

main proc far

; начало процедуры (main – имя процедуры; far– дальняя)

assume cs:codesg,ds:datasg,ss:stacksg ; директива, устанавливающая соответствие

;сегментных регистров (cs, ds, ss) сегментам (ее обычный вид для EXE-программы)

;следующие строки должны быть в любой EXE-программе:

push ds

 

 

; сохранение содержимого регистра ds в стеке (для возврата в DOS)

xor ax,ax

 

 

; ax:=0

 

push ax

 

 

; ячейка в стеке для MS-DOS (требование – д.б. равна нулю)

mov ax,datasg ; инициализация регистра ds (заносится адрес

mov ds,ax

 

 

; начала сегмента данных)

;---------

 

 

 

 

mov ax,0600h

;\

| ah=06(прокрутка),al=00(весь экран)

mov bh,07

 

 

; \

| нормальный атрибут (черно-белый)

mov cx,0000 ;

очистка экрана | верхняя левая позиция

mov dx,314fh

; /

| нижняя правая позиция

int 10h

 

 

;/

| передача управления в BIOS

mov ah,02 ;\

 

 

| установка курсора

mov bh,00 ; \

 

 

| экран 0

mov dh,00 ; управление курсором | строка 00

mov dl,00

; /

 

 

| столбец 00

int 10h

;/

 

 

| передача упр. в BIOS

snova:

 

 

 

 

xor ax,ax

 

;\

 

 

mov al,b1

 

; | b1+b2

 

add al,b2

 

; |

 

 

adc ah,0

 

;/

 

 

mov word ptr rezult,ax

; result := b1+b2

call bin_ASCII

 

;вызов процедуры перевода из bin (двоичное) в ASCII

;

 

 

 

результат – число в кодах ASCII – в ячейке ascval

mov ah,09h

 

 

; вывод на экран сообщения

lea dx,msg_b1b2

; "b1+b2="

int 21h

 

 

 

 

mov ah,09h

 

 

; вывод на экран

lea dx,ascval

 

 

; полученного результата (265=255+10)

int 21h

 

 

 

 

call cursor

 

 

 

 

xor dx,dx

 

;\

 

 

mov ax,w1

 

; | w1+w2

 

add ax,w2

 

; |

 

 

adc dx,0

 

;/

 

 

mov word ptr rezult,ax

 

 

 

 

 

107

 

mov word ptr rezult+2,dx

 

call bin_ASCII

 

;вызов процедуры перевода из bin (двоичное) в ASCII

;

mov ah,09h

 

 

результат – число в кодах ASCII – в ячейке ascval

 

 

 

; вывод на экран сообщения

 

lea dx,msg_w1w2

 

; "w1+w2="

 

int 21h

 

 

 

 

mov ah,09h

 

 

; вывод на экран

 

lea dx,ascval

 

 

; полученного результата (66535=65535+1000)

 

int 21h

 

 

 

 

call cursor

 

 

 

 

mov ax,w1

;\

 

 

 

sub al,b1

; | w1-b1

 

 

 

sbb ah,0

;/

 

 

; др. вариант разности:

 

 

;

xor ax,ax

 

 

 

;

mov al,b1

 

 

 

;

sub w1,ax

 

 

 

;

mov ax,w1

 

 

 

 

mov word ptr rezult,ax

 

 

call bin_ASCII

 

;вызов процедуры перевода из bin (двоичное) в ASCII

;

mov ah,09h

 

 

результат – число в кодах ASCII – в ячейке ascval

 

 

 

; вывод на экран сообщения

 

lea dx,msg_w1b1

 

; "w1-b1="

 

int 21h

 

 

 

 

mov ah,09h

 

 

; вывод на экран

 

lea dx,ascval

 

 

; полученного результата (65280=65535-255)

 

int 21h

 

 

 

 

call cursor

 

 

 

; В примере lab1pr6.asm:

 

;

mov ax,word ptr d1

;

 

; mov dx,word ptr d1+2

;

;

sbb ax,word ptr d2

;

 

; sbb dx,word ptr d2+2

 

;/ d1d2

;

mov word ptr rezult,ax

; младшее слово разности (в rezult и rezult+1)

;

mov word ptr rezult+2,dx ; старшее слово разности (в rezult+2 и rezult+3)

xor cx,cx

mov ax,word ptr d1 mov dx,word ptr d1+2 add ax,word ptr d2 adc dx,word ptr d2+2

;Т.к. сумма двух двойных слов не помещается в двойном слове, надо учесть перенос в

;старшее (третье) слово:

adc cx,0 ;cx:=cx+0+cf=0+0+(cf=1, если перенос был, или cf=0, если его не было)

;Сумма d1+d2 получается в трех регистрах: ax, bx и cx

;подготовка к вызову процедуры call bin_ASCII (она получает данные в ячейке rezult) mov word ptr rezult,ax

mov word ptr rezult+2,dx

 

mov word ptr rezult+4,cx

; rezult := d1+d2

 

108

; младшее слово разности (в rezult и rezult+1) ; старшее слово разности (в rezult+2 и rezult+3)
;вызов процедуры перевода из bin (двоичное) в ASCII результат – число в кодах ASCII – в ячейке ascval
; вывод на экран сообщения
; "d1-d2="

call bin_ASCII

;вызов процедуры перевода из bin (двоичное) в ASCII

;

результат – число в кодах ASCII – в ячейке ascval

mov ah,09h

; вывод на экран сообщения

lea dx,msg_d1d2

; "d1+d2="

int 21h

 

mov ah,09h

; вывод на экран полученного

lea dx,ascval

; результата (5147483647 =2147483647+3000000000)

int 21h

 

call cursor

 

mov ax,word ptr d1; mov dx,word ptr d1+2 ; sbb ax,word ptr d3 ;

sbb dx,word ptr d3+2;/ d1d3 mov word ptr rezult,ax

mov word ptr rezult+2,dx

call bin_ASCII

;

mov ah,09h

lea dx, msgd1_d3

int 21h

 

 

mov ah,09h

; вывод на экран полученного

lea dx,ascval

; результата (2000000000 =2147483647147483647)

int 21h

 

 

call cursor

 

 

mov ah,02 ;\

| установка курсора

mov bh,00 ; \

| экран 0

mov dh,24 ; управление курсором | строка 24

mov dl,00

; /

| столбец 00

int 10h

;/

| передача упр. в BIOS

mov ah,09h

; вывод на экран сообщения

lea dx,msg_e ; "Для выхода нажмите любую клавишу!"

int 21h

 

 

mov ah,0

;-ожидание нажатия клавиши

int 16h

;/

 

ret ;выход в DOS

main endp

;-процедуры-----------------------------

; сюда вставляются процедуры ASCII_bin_b, ASCII_bin_w

; и ASCII_bin_d из файла as_b_bwd.asm include as_b_bwd.asm

; сюда вставляется процедура bin_ASCII из файла bin_asci.asm

include bin_asci.asm

 

clrascval proc

 

mov cx,12

; было 20

mov si,11

; было 19

clr1: and ascval[si],30h dec si

109

loop clr1

 

ret

 

clrascval endp

 

cursor proc

;процедура перевода курсора на след. строку

mov ah,09

lea dx,perevod_cursora int 21h

ret

 

cursor endp

 

codesg ends

; конец сегмента

end main

; конец программы

===================================================================

Пример 1.7

;lab1pr7.asm ред. 11_07_05

;РАЗРАБОТАЛ МИШУРИН А.О., СТУДЕНТ ГРУППЫ 11БИ, ИЮЛЬ 2003 ГОДА. ;Программа (МП 8086) вычисляет по формулам: b1*b2; w1*w2; w1*b1; b1*w2. ;Компиляция:

;tasm.exe lab1pr7.asm

;tlink.exe lab1pr7.obj

;-сегмент стека---------------------------------

stacksg segment para stack 'Stack' db 1024 dup(?)

stacksg ends

;-сегмент данных-------------------------------

datasg segment para 'Data' msg_b1 db "b1=","$" msg_w1 db "w1=","$" msg_d1 db "d1=","$" msg_b1b2 db "b1*b2=","$" msg_w1w2 db "w1*w2=","$" msg_b1w2 db "b1*w2=","$" msg_w1b1 db "w1*b1=","$"

msg_e db "Для выхода нажмите любую клавишу!","$" msg_err1 db "Ошибка#1: ошибка ввода!","$"

ascval db "00000000000000000000","$" perevod_cursora db 0dh,0ah,"$"

; сюда вставляются списки параметров (из файла vvod_bwd.asm)

include vvod_bwd.asm

; директива, вставляющая в текст программы содержимое

;

указанного файла vvod_bwd.asm )

b1 db 255

b2 db 10

w1 dw 65535

w2 dw 1000

d1 dd 2147483647

d2 dd 3000000000 prom dw 0 promd dd 0

fml dd 0

110

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