1011
.pdfcmp 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 |
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