ПРИМЕРЫ (ТЕКСТЫ) ПРОГРАММ
Пример 1.1
;lab1pr1.asm ред. 03_11_05
;РАЗРАБОТАЛ МИШУРИН А.О., СТУДЕНТ ГРУППЫ 11БИ, ИЮЛЬ 2003 ГОДА. ;Программа (работает с МП 8086) выводит на экран сообщение "Привет, уважаемый
;пользователь!" + ожидает нажатия клавиши пользователем
;Компиляция: tasm.exe lab1pr1.asm
;tlink.exe lab1pr1.obj
;-сегмент стека---------------------------------
stacksg segment para stack 'Stack' ; segment – директива, показывающая начало
|
db 32 dup(?) |
|
; |
сегмента с именем stacksg |
|
stacksg ends |
|
|
; ends – директива, показывающая конец этого сегмента |
||
;-сегмент данных---------------------------------- |
|
|
|
||
datasg segment para 'Data' |
; segment – директива, показывающая начало |
||||
; |
|
|
|
|
сегмента с именем datasg |
msg |
db "Привет, уважаемый пользователь!","$" |
||||
msg_e db "Для выхода нажмите любую клавишу!","$" |
|||||
datasg ends |
|
|
; ends – директива, показывающая конец этого сегмента |
||
;- сегмент кода---------------------------------- |
|
|
|
|
|
codesg segment para 'Code' ; директива, показывающая начало сегмента codesg |
|||||
main proc far |
|
; proc– директива, показывающая начало процедуры с именем main |
|||
|
assume cs:codesg,ds:datasg,ss:stacksg |
; директива, устанавливающая |
|||
; |
|
|
|
соответствие сегментных регистров (cs, ds, ss) сегментам |
|
; следующие пять строк должны быть в любой EXE-программе |
|||||
|
push ds |
|
; сохранение содержимого регистра ds в стеке (для возврата в DOS) |
||
|
xor ax,ax |
|
|
|
|
|
push ax |
|
|
|
|
|
mov ax,datasg |
; инициализация регистра ds (заносится адрес |
|||
|
mov ds,ax |
; начала сегмента данных) |
|||
;--------- |
вывод на экран сообщения |
|
|||
mov ah,09h |
|
; функция вывода на экран (регистр ah:=09h) |
|||
lea dx,msg |
|
; загрузить в регистр dx адрес начала строки |
|||
; |
|
|
|
«Привет, уважаемый пользователь» |
|
int 21h |
|
; передача управления DOS |
|||
;--------- |
вывод на экран сообщения |
|
|||
mov ah,09h |
|
; функция вывода на экран (регистр ah:=09h) |
|||
lea dx,msg_e |
|
; загрузить в регистр dx адрес начала строки |
|||
int 21h |
|
; "Для выхода нажмите любую клавишу!" |
|||
mov ah,0 |
|
; ожидание нажатия клавиши |
|||
int 16h |
|
|
|
|
|
ret |
|
|
; возврат в DOS |
|
|
main endp |
|
; ends – директива, показывающая конец процедуры main |
|||
codesg ends |
|
; ends – директива, показывающая конец сегмента codesg |
|||
end main |
; end – директива, показывающая конец программы и определяющая |
||||
; входную точку программы, с которой начинается выполнение программы, т.е. main
– первая цифра в номере примера (до точки) обозначает номер части учебного пособия «Языки программирования»
91
Пример 1.2
;lab1pr2.asm ред. 02_06_05
;РАЗРАБОТАЛ МИШУРИН А.О., СТУДЕНТ ГРУППЫ 11БИ, ИЮЛЬ 2003 ГОДА. ;Программа (работает с МП 8086) обеспечивает ввод с клавиатуры байта + ;перевод из кодов ASCII (символы) в bin (двоичное число).
;Компиляция: tasm.exe lab1pr2.asm
;tlink.exe lab1pr2.obj
;-сегмент стека---------------------------------
stacksg segment para stack 'Stack' ; para – параграф (сегмент должен начинаться с
; |
адреса, кратного шестнадцати, т.е. на границе параграфа) |
db 32 dup(?) |
;стек состоит из 32 байтов |
stacksg ends |
; конец сегмента |
;-сегмент данных---------------------------------- |
|
datasg segment para 'Data' ;сегмент данных тоже должен начинаться на границе
; |
параграфа |
msg_b1 db "b1=",0dh,0ah, "$" |
|
msg_e db "Для выхода нажмите любую клавишу!",0dh,0ah,"$" msg_err1 db "Ошибка#1: ошибка ввода!",0dh,0ah,"$"
; Список параметров для ввода переменной, значение которой вмещается в один байт vvod_b label byte
maxlen_b db 4 ;максимальное кол-во символов, вводимых с клавиатуры, вкл. ENTER fact_b db 0 ;фактическое кол-во символов, вводимых с клавиатуры, вкл. код ENTER simv_b db "0000" ;сюда вводятся символы в ASCII-(1 как 31h, 2 как 32h и т.д.)
b1 db 0 |
; двоичное значение переменной b1 (сюда оно заносится после |
|
; преобразования процедурой ASCII_bin-b) |
prom dw 0 |
; рабочие ячейки процедуры ASCII_bin_b |
osh_v db 0 |
|
datasg ends |
; конец сегмента данных |
;- сегмент кода---------------------------------- |
|
codesg segment para 'Code' |
|
main proc 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 |
; начала сегмента данных) |
snova: |
|
mov ah,09h |
; функция вывода на экран сообщения (регистр ah=09) |
lea dx,msg_b1 |
; загрузить в dx адрес начала строки «b1= » |
int 21h |
; передача управления DOS |
mov ah,0ah |
; функция ввода с клавиатуры (ah=0ah) |
lea dx,vvod_b |
; загрузить адреса списка параметров |
int 21h |
; передача управления в DOS |
call ASCII_bin_b ; вызов процедуры преобразования из кодов ASCII в двоичный |
|
; |
(bin) для переменной, помещающейся в байт |
|
92 |
mov b1,al ;занесение полученного значения из al в ячейку памяти b1 ; проверка признака ошибки (osh_v=0 – во введенных данных нет ошибки; ; osh_v не равна (<>) нулю, означает ошибку).
cmp osh_v, 0 ; сравнение и присвоение zf:=1, если операнды равны, т.е. osh_v =0
;или zf:=0, если операнды не равны, т.е. osh_v <> 0(есть ошибка)
jz s1 |
; переход на метку s1, если флаг нуля (zf) =1 |
; |
иначе переход к следующей команде (jmp snova) |
jmp snova |
;безусловный переход на метку snova |
s1:
mov ah,09h
lea dx,msg_e ; вывод на экран сообщения “Для выхода нажмите любую клавишу!"
int 21h |
|
mov ah,0 |
; ожидание нажатия клавиши |
int 16h |
|
ret |
;возврат в DOS |
main endp |
|
;-процедуры |
----------------------------- |
ASCII_bin_b proc ;процедура перевода из ASCII в bin для байта
;(Вход: в ячейке simv_b списка параметров введенные символы (цифры!) вASCII-кодах;
;в ячейке fact_b – количество введенных символов, включая код клавиши ENTER
;выход: al= двоичное число; при вводе не цифры - osh_v :=1) xor ax,ax
xor cx,cx
mov prom,0 |
|
mov osh_v,0 |
|
mov al,fact_b |
|
mov cl,al |
|
dec al |
|
mov si,ax |
|
mov bx,1 |
|
met1_b: |
|
mov al,simv_b[si] |
|
cbw |
; преобразование байта в слово (ax:=al). Способ – распространение |
;знака (в регистре al) на старший байт слова (в регистре ax)
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) mul bx
add prom,ax mov ax,bx mov bx,10 mul bx mov bx,ax
93
dec si |
|
loop met1_b |
|
mov ax,prom |
|
jmp end_error_b |
;безусловный переход на метку end_error_b |
error_b: |
|
mov ah,09h |
; вывод на экран сообщения |
lea dx,msg_err1 |
; "Ошибка#1: ошибка ввода |
int 21h |
|
mov osh_v,1 |
; osh_v := 1 |
end_error_b: |
|
ret |
; возврат в DOS |
ASCII_bin_b endp ; endp – директива, показывающая конец процедуры ASCII_bin_b
codesg ends |
; ends – директива, показывающая конец сегмента codesg |
end main |
; end – директива, показывающая конец программы и определяющая |
; входную точку программы (точку, с которой начинается выполнение программы)
==================================================================
Пример 1.3
;lab1pr3.asm ред. 17_12_05
;РАЗРАБОТАЛ МИШУРИН А.О., СТУДЕНТ ГРУППЫ 11БИ, ИЮЛЬ 2003 ГОДА. ;Программа (работает с МП 8086) обеспечивает ввод с клавиатуры слова
;+ перевод из кодов ASCII (символы) в bin (двоичное число). ;Компиляция: tasm.exe lab1pr3.asm
;tlink.exe lab1pr3.obj
;-сегмент стека---------------------------------
stacksg segment para stack 'Stack' ; segment – директива, показывающая начало
db 128 dup(?) |
; |
сегмента с именем stacksg |
stacksg ends |
; ends – директива, показывающая конец этого сегмента |
|
;-сегмент данных---------------------------------- |
|
|
datasg segment para 'Data' |
; segment – директива, показывающая начало |
|
; |
|
сегмента с именем datasg |
msg_b1 db "b1=",0dh,0ah,"$" |
|
|
msg_w1 db "w1=",0dh,0ah,"$"
msg_e db "Для выхода нажмите любую клавишу!", 0dh,0ah,"$" msg_err1 db "Ошибка#1: ошибка ввода!", 0dh,0ah,"$"
ascval db "00000000000000000000",0dh,0ah,"$" perevod_cursora db 0dh,0ah,"$"
;строки от директивы COMMENT @ до символа @ не используются (закомментированы)
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;максимальное кол-во символов, вводимых с клавиатуры, вкл. ENTER fact_w db 0 ;фактическое кол-во символов, вводимых с клавиатуры, вкл. код ENTER
94
simv_w db "000000" |
;сюда вводятся символы в ASCII-(‘1’ как 31h, ‘2’ как 32h и т.д.) |
b1 db 0 |
; в данном примере не используется |
w1 dw 0 |
; двоичное значение переменной w1 (сюда оно заносится после |
|
; преобразования процедурой ASCII_bin_w) |
prom dw 0 |
; рабочие ячейки процедуры ASCII_bin_w |
osh_v db 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: |
|
|
mov ah,09h |
; функция вывода на экран сообщения (ah=09) |
|
lea dx,msg_w1 |
; загрузить адрес начала строковой переменной в dx |
|
int 21h |
; передача управления DOS |
|
mov ah,0ah |
; функция ввода с клавиатуры (ah=0ah) |
|
lea dx,vvod_w |
; загрузить адреса списка параметров |
|
int 21h |
; передача управления в DOS |
|
call ASCII_bin_w ;вызов процедуры перевода из ASCII в двоичный |
||
; |
(bin) для переменной, помещающейся в слово |
|
mov w1,ax |
;занесение полученного значения из ax в ячейку памяти w1 |
|
; проверка признака ошибки (osh_v=0 – во введенных данных нет ошибки; |
||
; |
|
osh_v не равна (<>)нулю, означает ошибку). |
cmp osh_v,0 ;сравнение и присвоение zf:=1, если операнды равны, т.е. если osh_v =0,
;если же операнды не равны, т.е. если osh_v <> 0(есть ошибка), то zf:=0
jz s1 |
; переход на метку s1, если установлен флаг нуля (zf) =1 |
; |
иначе переход к следующей команде (jmp snova) |
jmp snova |
;безусловный переход на метку snova |
s1: |
|
mov ah,02 |
; установка курсора |
|
95 |