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