Программирование на ассемблере 8086 — лабораторная
Лабораторная работа № 1
По теме : «Программирование на ассемблере 8086: структура программы и инструментальные средства»
Цель работы: Получить общее представление о языке ассемблер для процессоров x86. Получить практические навыки работы с инструментальными средствами ассемблера: транслятором, редактором связей (компоновщиком) и отладчиком.
com – программа
; Выводит на экран сообщение "Hello World!" и завершается
.model tiny ; модель памяти, используемая для СОМ
.code ; начало сегмента кода
org 100h ; начальное значение счетчика — 100h
start: mov ah,9 ; номер функции DOS — в АН
mov dx, offset message ; адрес строки — в DX
int 21h ; вызов системной функции DOS
ret ; завершение СОМ-программы
message db "Hello World!",0Dh,0Ah,’$’ ; строка для вывода
end start ; конец программы
exe – программа
Выводит на экран сообщение "Hello World!" и завершается
.model small ; модель памяти, используемая для ЕХЕ
.stack 100h ; сегмент стека размером в 256 байт
.code
start: mov ax, DGROUP ; сегментный адрес строки message
mov ds, ax ; помещается в DS
mov dx, offset message
mov ah,9
int 21h ; функция DOS "вывод строки"
mov ax,4C00h
int 21h ; функция DOS "завершить программу"
.data
message db "Hello World!",0Dh,0Ah,’$’
end start
Александров А. А. АВБ – II – 025
Лабораторная работа № 2
По теме: «Программирование на языке ассемблера. Команды пересылки данных, передачи управления, арифметических операций и управления циклами. Режимы адресации»
Цель работы: Изучить структуру программы на языке ассемблера, формат операторов ассемблера и директивы ассемблера, в том числе:
l директивы определения данных
l директивы определения сегментов.
Ознакомиться с основными операторами ассемблера и назначением имён выражениям. Изучить способы адресации и режимы переходов. Изучить команды пересылки данных, передачи управления и управления циклами. Получить практические навыки разработки программы на ассемблере, её программирования и отладки.
Задание: протабулировать функцию y = 3x – 2z + xz в интервалах x[0 .. 10], z[5 .. 15].
exe – программа
.MODEL small
.stack 256
.data
mass_X dw 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;исходный массив X
mass_Z dw 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ;исходный массив Z
message_Y db " Y = ",’$’
message_X db " X = ",’$’
message_Z db " Z = ",’$’
message db " ",0Dh,0Ah,’$’
.code
print proc
push ax ;сохраняем регистры
push cx
push dx
push bx
push si
mov si, ax ;запоминаем число
mov bx,10 ;основание системы
xor cx, cx ;в сх будет количество цифр в десятичном числе
test ax, ax ;если число положительное
jns m1 ;то пропускаем
neg ax ;если отрицательное, то меняем знак
m1:
xor dx, dx
div bx ;делим число на степени 10
push dx ;и сохраняем остаток от деления (коэффициенты при степенях) в стек
inc cx ;увеличиваем количество десятичных цифр числа
test ax, ax ;после деления остался 0?
jnz m1 ;если нет, продолжаем
test si, si ;число отрицательное?
jns m3 ;если нет, пропустить
push -3 ;иначе дописать перед числом минус
inc cx ;увеличить количество цифр числа
m3:
mov ah,2 ;ф-я вывода символа
m2:
pop dx ;взять из стека цифру числа
add dl, ‘0’ ;преобразовываем цифру в ASCII символ
int 21h ;вывести на экран
loop m2 ;все цифры
pop si ;восстанавливаем регистры
pop bx
pop dx
pop cx
pop ax
ret ;выход из подпрограммы
print endp
next proc
push ax
push dx
mov ah,9 ; номер функции DOS — в АН
mov dx, offset message ; адрес строки — в DX
int 21h ; вызов системной функции DOS
pop dx
pop ax
ret
next endp
msg_y proc
push ax
push dx
mov ah,9 ; номер функции DOS — в АН
mov dx, offset message_Y ; адрес строки — в DX
int 21h ; вызов системной функции DOS
pop dx
pop ax
ret
msg_y endp
msg_x proc
push ax
push dx
mov ah,9 ; номер функции DOS — в АН
mov dx, offset message_X ; адрес строки — в DX
int 21h ; вызов системной функции DOS
pop dx
pop ax
ret
msg_x endp
msg_z proc
push ax
push dx
mov ah,9 ; номер функции DOS — в АН
mov dx, offset message_Z ; адрес строки — в DX
int 21h ; вызов системной функции DOS
pop dx
pop ax
ret
msg_z endp
start:
mov ax, @data ; сегментный адрес
mov ds, ax ; помещается в DS
xor bp, bp ;обнуление регистра
mov cx, 11 ; счетчик
go:
mov si, bp
shl si,1
call msg_z
mov ax, mass_Z[si] ;z
call print
mov bx, ax
call msg_x
mov ax, mass_X[si] ;x
call print
call msg_y
mov di, ax ;x
sal di, 1 ;2x
add di, ax ;3x — di
mov bx, bx ;z
mul bx ;zx — ax
add ax, di ;3x+zx — ax
sal bx, 1 ;2z — bx
sub ax, bx ;3x-2z+zx — ax
call print
call next
inc bp ;переходим к следующему элементу
loop go
mov ax, 4c00h ; функция DOS "завершить программу"
int 21h
end start
Александров А. А. АВБ – II – 025
Лабораторная работа № 3
По теме: «Программирование символьного ввода — вывода с сипользованием средств dos и bios на языке ассемблера»
Цель работы: Изучить программные прерывания (функции) dos, bios предназначенные для ввода вывода символьной информации на дисплей и с клавиатуры. Получить практические навыки программирования организации текстового интерфейса и работы с псевдографикой.
exe – программа
.model tiny
.stack 100h
.data
string0 db ‘ #### ‘, ‘$’
string1 db ‘ ## ## ‘, ‘$’
string2 db ‘ ## ## ‘, ‘$’
string3 db ‘ ############ ‘, ‘$’
string4 db ‘##############’, ‘$’
string5 db ‘## ##’, ‘$’
string6 db ‘## ##’, ‘$’
string7 db ‘## ##’, ‘$’
X db 0 ; координата X курсора
Y db 0 ; координата Y курсора
emptystring db 80 dup (‘ ‘),’$’
.code
clrscr proc ; функция очистки экрана
push ax
push bx
push dx
push cx
mov bl, 0
mov cx,24
repeat:
mov bh, 0
mov ah, 2 ; функция ‘установить курсор’
mov al, 0
mov dl, 0 ; номер строки
mov dh, bl ; номер колонки
int 10h ; программное прерывание — видеосервис bios
inc bl
mov dx, offset emptystring
mov ah,9 ; вывод строки числа
int 21h
loop repeat
pop cx
pop dx
pop bx
pop ax
ret
clrscr endp
print proc
mov dh, Y ;координата Y курсора по вертикали
mov dl, X ;координата X курсора по горизонтали
mov ah, 02h ; функция ‘установить курсор’
int 10h ; программное прерывание
mov dx, offset string0 ; вывод строки
mov ah, 9h ; вывод строки числа
int 21h ; программное прерывание
inc Y ; увеличить координату на единицу
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string1
mov ah, 9h
int 21h
inc Y
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string2
mov ah, 9h
int 21h
inc Y
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string3
mov ah, 9h
int 21h
inc Y
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string4
mov ah, 9h
int 21h
inc Y
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string5
mov ah, 9h
int 21h
inc Y
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string6
mov ah, 9h
int 21h
inc Y
mov dh, Y
mov dl, X
mov ah, 02h
int 10h
mov dx, offset string7
mov ah, 9h
int 21h
sub Y, 7 ; вернуть курсор в начальное положение
ret
print endp
UP proc ; перемешение курсора вверх
call clrscr
dec Y ; -1
cmp Y, 0 ; проверка на выход за пределы поля
js UU
UUP:
jmp zapros ; Переход на метку ZAPROS
UU:
inc Y ; вернуть курсор в начальное положение
jmp UUP
UP endp
DOWN proc ; перемешение курсора вниз
call clrscr
inc Y ; +1
cmp Y, 17
Je DO2
DDW1:
jmp zapros
DO2:
dec Y
jmp DDW1
DOWN endp
LEFT proc ; перемешение курсора влево
call clrscr
dec X
cmp X, 0
js LL
LLF:
jmp zapros
LL:
inc X
jmp LLF
LEFT endp
RIGHT proc ; перемешение курсора вправо
call clrscr
inc X
cmp X, 67
Je RR
RRG:
jmp zapros
RR:
dec X
jmp RRG
RIGHT endp
start:
mov ax, @data ; сегментный адрес
mov ds, ax ; помещается в DS
call clrscr ; очистить экран
zapros:
call print
mov ah,7h ; Запрос нажатия клавиши
int 21h ; программное прерывание
cmp al,’w’ ; сравнение с кодом клавиши
je UP ; переход на процедуру UP, если код совпал
cmp al,’x’
je DOWN
cmp al,’a’
je LEFT
cmp al,’d’
je RIGHT
cmp al, 1Bh ; выходить по ESC
je EXIT
loop zapros;
EXIT:
xor dx, dx
mov ax, 4c00h ; функция завершить программу
int 21h
end start
Александров А. А. АВБ – II – 025
Лабораторная работа № 4
По теме: «Задание пользовательского обработчика прерывания таймера»
exe – программа
.model small ; модель памяти, используемая для ЕХЕ
org 256
Data SEGMENT
message db "User Timer Interrupt Handler",0Dh,0Ah,’$’
message1 db "it work..",0Dh,0Ah,’$’
message2 db "end of programm",0Dh,0Ah,’$’
emptystring db 80 dup (‘ ‘),’$’
old_handler dd 0
count db 0
symbol db 50h
Data ENDS
Code SEGMENT
ASSUME cs: Code, ds: Data
clrscr proc ; функция очистки экрана
mov bl, 0
mov cx,24
repeat:
mov bh, 0
mov ah, 2 ; функция ‘установить курсор’
mov al, 0
mov dl, 0 ; номер строки
mov dh, bl ; номер колонки
int 10h ; программное прерывание — видеосервис bios
inc bl
mov dx, offset emptystring
mov ah,9 ; вывод строки числа
int 21h
loop repeat
ret
clrscr endp
int_handler proc far
push ax
push dx
push bx
push ds
pushf
call cs:old_handler
inc count
cmp count, 18 ; счетчик
jnz End_Of_User_Handler ; проверка равен счетчик 18
mov count, 0 ;обнуление счетчика
cmp symbol, 0h
jz namber ; проверка равен символ 0h, Переход на метку
cmp symbol, 50h
jz new_line ; проверка равен символ 50h, Переход на метку
mov ah, 14 ; номер функции DOS — в АН
mov al, symbol ; вывод строки числа
int 10h ; вызов системной функции DOS
inc symbol ; увеличить на единицу
jmp End_Of_User_Handler
new_line:
mov bh, 0
mov ah, 2 ;функция ‘установить курсор’
mov al, 0
mov dl, 38 ; номер колонки
mov dh, 12 ; номер строки
int 10h ; программное прерывание
mov cx, 20 ; счетчик
ckl:
mov ah, 14
mov al, ‘ ‘
int 10h
loop ckl
namber:
mov bh, 0
mov ah, 2
mov al, 0
mov dl, 38
mov dh, 12
int 10h
mov al, 41h
mov symbol, al
End_Of_User_Handler:
mov al, 20h ; завершение функции
out 20h, al
pop ds
pop bx
pop dx
pop ax
iret ; выйти из функции
int_handler endp
start:
mov ax, Data ; сегментный адрес строки message
mov ds, ax ; помещается в DS
call clrscr ; очистить экран
mov bh, 0
mov ah, 2 ; функция ‘установить курсор’
mov al, 0
mov dl, 26 ; номер колонки
mov dh, 0 ; номер строки
int 10h ; программное прерывание — видеосервис bios
mov dx, offset message
mov ah, 9 ; вывод строки заголовка
int 21h
mov ah, 2 ; функция ‘установить курсор’
mov al, 0
mov dl, 26 ; номер колонки
mov dh, 12 ; номер строки
int 10h ; программное прерывание — видеосервис bios
mov dx, offset message1
mov ah,9 ; вывод строки числа
int 21h
; скопировать адрес предыдущего обработчика в переменную old_handler
mov ax,3508h ; АН = 35h, AL = 08h номер прерывания
int 21h ; функция DOS: считать адрес обработчика прерывания
mov word ptr old_handler, bx ; возвратить смещение в ВХ
mov word ptr old_handler+2,es ; сегментный адрес в ES,
;установить наш обработчик
mov ax,2508h ; АН = 25h, AL = номер прерывания
mov dx, seg int_handler ; сегментный адрес
mov ds, dx ; в DS
mov dx, offset int_handler ; смещение в DX нашего обработчика
int 21h ; функция DOS: установить
mov ax, Data ; сегментный адрес строки message
mov ds, ax ; помещается в DS обработчик
; ожидание ввода любого символа
mov ah,7
mov al,0
int 21h
; восстановить предыдущий обработчик
lds dx, old_handler ; сегментный адрес в DS и смещение в DX
mov ax,2508h ; АН = 25h, AL = номер прерывания
int 21h ; установить обработчик
mov ax, Data ; сегментный адрес строки message
mov ds, ax ; помещается в DS обработчик
; вывести сообщение: конец программы
mov bh, 0
mov ah, 2 ; функция ‘установить курсор’
mov al, 0
mov dl, 27 ; номер строки
mov dh, 23 ; номер колонки
int 10h ; программное прерывание — видеосервис bios
mov dx, offset message2
mov ah,9 ; вывод строки числа
int 21h
; завершить программу
mov ax,4C00h
int 21h ; функция DOS "завершить программу"
Code ENDS
end start
Александров А. А. АВБ – II – 025
Лабораторная работа № 5
По теме: «Исследование кооперативной многозадачности»
Цель работы:
● изучить методы совместного выполнения нескольких вычислительных процессов на основе принципов невытесняющей многозадачности;
● получить навыки разработки соответствующего программного обеспечения, обеспечения.
exe – программа
.model tiny
.stack 100h
.code
.386
org 100h
start:
mov ax, cs
mov ds, ax
call clrscr
jmp init ; вызов подпрограммы инициализации системных данных
; резервируем память для области стека каждого ‘пользовательского’ процесса и процесса командного интерпретатора
st0 dw 128 dup(0)
st1 dw 128 dup(0)
st2 dw 128 dup(0)
st3 dw 128 dup(0)
st4 dw 128 dup(0)
; резервируем память под системные таблицы для 5-ти процессов
stab dw 5 dup(0) ; таблица сегментной части адреса стека процессов
ptab dw 5 dup(0) ; таблица части ‘смещене’ адреса стека процессов
sost dw 5 dup(0) ; таблица состояния процессов
pida dw 0 ; идентификатор текущего процесса
; системный процесс — интерпретатор команд пользователя
komand proc far
jmp avtomat
;данные для работы автомата (интерпретатора)
s db 1 ;состояние автомата
; 1 — автомат ожидает ввод пользователем команды
; 2 — автомат ожидает ввод пользователем параметра команды
progress dw 0 ;команда
; 0 — остановить процесс
; 1 — запустить процесс
emptystring db 80 dup (‘ ‘),’$’
avtomat: ; автомат с двумя сстояниями
cmp s, 1
je sost1
cmp s, 2
je sost2
sost1: ;ввод команды
mov ah, 6
mov dl, 0ffh
int 21h
cmp al, ‘q’ ; команда q?
jne m11
mov ah, 4ch ; да — завершить работу
int 21h
m11:
cmp al, ‘s’ ; команда s?
jne m12
mov progress,0 ; команда — приостановить работу
jmp sost2
m12:
cmp al, ‘g’ ; команда g?
jne m13
mov progress,1 ;команда — продолжить работу
jmp sost2
m13:
mov s, 1 ; неизвестная команда
jmp exit
sost2: ; ввод параметра (номера пользовательского процесса)
mov ah, 6
mov dl, 0ffh
int 21h
cmp al, ‘1’
jne m21
mov ax, progress
mov sost[0],ax
jmp sost1
m21:
cmp al, ‘2’
jne m22
mov ax, progress
mov sost[2],ax
jmp sost1
m22:
cmp al, ‘3’
jne m23
mov ax, progress
mov sost[4],ax
jmp sost1
m23:
cmp al, ‘4’
jne m24
mov ax, progress
mov sost[6],ax
jmp sost1
m24:
mov s, 2
exit:
call delay ; задержка (для удобства восприятия работы программ)
call dispetcher ; передача управления диспетчеру процессов
jmp avtomat ; ‘зацикливание’ автомата
ret far
endp ; конец процедуры ‘komand’
; первый пользовательский процесс
proc1 proc far
jmp data1 ; обход области данных
text1 db "11111111"
clrscr1 db " ",’$’
length1 db 8
posx1 db 0
data1:
cycl1:
mov al, length1
mov bl, posx1
cmp al, bl
jz clear1
mov ah, 02h
mov bh, 0
mov dh, 2
mov dl, bl
add dl, 2
int 10h
mov dl, text1[bx]
mov dh, 2
mov ah, 6h
int 21h
inc bx
mov posx1, bl
jmp goto1
clear1:
mov posx1, 0
mov ah, 02h
mov bh, 0
mov dh, 2
mov dl, 2
int 10h
mov ah, 09h
mov dx, offset clrscr1
int 21h
goto1:
call delay
call dispetcher
jmp cycl1
ret far
endp
; второй пользовательский процесс
proc2 proc far
jmp data2 ; обход области данных
text2 db "222222"
clrscr2 db " ",’$’
length2 db 4
posx2 db 0
data2:
cycl2:
mov al, length2
mov bl, posx2
cmp al, bl
jz clear2
mov ah, 02h
mov bh, 0
mov dh, 2
mov dl, bl
add dl, 41
int 10h
mov dl, text2[bx]
mov dh, 2
mov ah, 6h
int 21h
inc bx
mov posx2, bl
jmp goto2
clear2:
mov posx2, 0
mov ah, 02h
mov bh, 0
mov dh, 2
mov dl, 41
int 10h
mov ah, 09h
mov dx, offset clrscr2
int 21h
goto2:
call delay
call dispetcher
jmp cycl2
ret far
endp
; третий пользовательский процесс
proc3 proc far
jmp data3 ; обход области данных
text3 db "3333333333333"
clrscr3 db " ",’$’
length3 db 13
posx3 db 0
data3:
cycl3:
mov al, length3
mov bl, posx3
cmp al, bl
jz clear3
mov ah, 02h
mov bh, 0
mov dh, 21
mov dl, bl
add dl, 2
int 10h
mov dl, text3[bx]
mov dh, 2
mov ah, 6h
int 21h
inc bx
mov posx3, bl
jmp goto3
clear3:
mov posx3, 0
mov ah, 02h
mov bh, 0
mov dh, 21
mov dl, 2
int 10h
mov ah, 09h
mov dx, offset clrscr3
int 21h
goto3:
call delay
call dispetcher
jmp cycl3
ret far
endp
; 4-й пользовательский процесс
proc4 proc far
jmp data4 ; обход области данных
text4 db "4444444"
clrscr4 db " ",’$’
length4 db 7
posx4 db 0
data4:
cycl4:
mov al, length4
mov bl, posx4
cmp al, bl
jz clear4
mov ah, 02h
mov bh, 0
mov dh, 21
mov dl, bl
add dl, 41
int 10h
mov dl, text4[bx]
mov dh, 2
mov ah, 6h
int 21h
inc bx
mov posx4, bl
jmp goto4
clear4:
mov posx4, 0
mov ah, 02h
mov bh, 0
mov dh, 21
mov dl, 41
int 10h
mov ah, 09h
mov dx, offset clrscr4
int 21h
goto4:
call delay
call dispetcher
jmp cycl4
ret far
endp
;диспетчер процессов
dispetcher proc
pusha
mov bx, pida
mov ptab[bx], sp
mov stab[bx], ss
perechod1:
cmp bx, 8
je perechod2
add bx, 2
jmp perechod3
add bx,2
jmp perechod4
perechod2:
mov bx, 0
perechod3:
mov dx, sost[bx]
and dx, 1h
jz perechod1
mov pida, bx
mov sp, ptab[bx]
mov ax, stab[bx]
perechod4:
mov dx, sost[bx]
and dx, 1h
jz perechod1
mov pida, bx
mov sp, ptab[bx]
mov ax, stab[bx]
mov ss, ax
popa
ret
endp
; инициализация системных параметров
;инициализация процесса 1
init:
mov sp, offset st0+254
push cs
mov ax, offset proc1
push ax
mov stab[0], ss
mov ptab[0], sp
mov sost[0], 1
;инициализация процесса 2
mov sp, offset st1+254
push cs
mov ax, offset proc2
push ax
pusha
mov stab[2], ss
mov ptab[2], sp
mov sost[2], 1
;инициализация процесса 3
mov sp, offset st2+254
push cs
mov ax, offset proc3
push ax
pusha
mov stab[4], ss
mov ptab[4], sp
mov sost[4], 1
;инициализация процесса 4
mov sp, offset st3+254
push cs
mov ax, offset proc4
push ax
pusha
mov stab[8], ss
mov ptab[8], sp
mov sost[8], 1
; инициализация системного процесса (интерпретатора команд)
mov sp, offset st4+254
push cs
mov ax, offset komand
push ax
pusha
mov stab[16], ss
mov ptab[16], sp
mov sost[16], 1
mov sp, ptab[0]
mov ax, stab[0]
mov ss, ax
jmp dispetcher
; подпрограмма задержки
delay proc
mov cx, 10000
delay1:
push cx
mov cx, 10000
delay_1:
MOV ax, 1
loop delay_1
pop cx
loop delay1
ret
endp
; подпрограмма очистки экрана
clrscr proc
mov bl,0
mov cx,24
repeat:
mov bh, 0
mov ah, 2 ; функция ‘установить курсор’
mov al, 0
mov dl, 0 ; номер строки
mov dh, bl ; номер колонки
int 10h ; программное прерывание — видеосервис bios
inc bl
mov dx, offset emptystring
mov ah,9 ; вывод строки числа
int 21h
loop repeat
ret
end start