Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторна робота СП.docx
Скачиваний:
1
Добавлен:
08.09.2019
Размер:
3.28 Mб
Скачать

Лабораторна робота 9.

Тема: Процедури мовою асемблера

Ціль: Ознайомиться з особливостями організації процедур на асемблері і способами предачі параметрів у процедури.

Даны два массива однобайтовых чисел без знака. Найти сумму их максимальных элементов.

Опишем нахождение максимального элемента массива процедурой.

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

1) начальный адрес массива

2) количество элементов массива

Будем передавать параметры через регистры. Адрес массива - через регистр BX

Кол-во элементов - через CX

Результат возвращаем основной программе через AL (эл-ты однобайтовые).

Masm

model small

.stack 128

.data

n equ 10

m equ 15

mas1 db n dup (?)

mas2 db m dup (?)

; процедура находит максимальный элемент массива

; адрес массива находится в регистре BX

; кол-во элементов - в CX

; результат возвращаем через AL

max proc

mov al,0 ;

sled: cmp [bx],al

jle new

mov al,[bx]

new: inc bx

loop sled

ret

max endp

start: . . .

lea bx,mas1

mov cx,n

call max ; результат в al

mov dl,al

lea bx,mas2

mov cx,m

call max

add dl,al

. . .

end start

Лабораторна работа 10-11.

Тема. Введення/виведення даних.

Ціль: Ознайомитися з методами введення даних з клавіатури та методами виведення даних на екран.

Приклад 1

format pe

; dosoutl. asm

; Виводить на екран усі ASCII-символи

;

org 100h ; початок Сома-файлу

use16

mov cx, 256 ; вивести 256 символів

mov dl,0 ; перший символ - з кодом 00

mov ah,2 ; номер функції DOS “вивід символу”

cloop: int 21h ; виклик DOS

inc dl ; збільшення DL на 1 - наступний символ

test dl,0Fh ; якщо DL не кратний 16,

jnz continue_loop ; продовжити цикл,

push dx ; інакше: зберегти поточний символ

mov dl,0Dh ; вивести CR

int 21h

mov dl,0Ah ; вивести LF

int 21h

pop dx ; відновити поточний символ

continue_loop:

loop cloop ; продовжити цикл

ret

Приклад 2

; biosout. asm

; Виводить на екран усі ASCII-символи без винятку

format pe

org 100h ; Початок Сома-файлу

use16

start:

mov ax,0003h

int 10h ; Відеорежим 3 (очищення екрана

; і установлення курсору в 0, 0)

mov dx,0 ; DH і DL будуть використовуватися

; для збереження положення курсору.

; Початкове положення - 0,0

mov si,256 ; SI буде лічильником циклу

mov al,0 ; Перший символ - з кодом 00h

mov ah,9 ; Номер відеофункції “вивід символу з атрибутом”

mov cx,1 ; Виводиться один символ за раз

mov bl,00011111b

; атрибут символу - білий на синьому

cloop:

int 10h ; Вивести символ на екран

push ax ; Зберегти поточний символ і номер функції

mov ah,2 ; Номер відеофункції 2 -

; змінити положення курсору

inc dl ; Збільшити поточний стовпець на 1

int 10h ; Перемістити курсор

mov ax,0920h; АН = 09, AL = 20h (ASCII-код пробілу)

int 10h ; Вивести пробіл

mov ah,2 ; Номер відеофункції 2

inc dl ; Збільшити стовпець на 1

int 10h ; Перемістити курсор

pop ax ; Відновити номер функції в ah

; і поточний символ у al

inc al ; Збільшити AL на 1 - наступний символ

test al,0Fh ; Якщо AL не кратний 16,

jnz continue_loop

; продовжити цикл,

push ax ; інакше - зберегти номер функції

; і поточний символ

mov ah,2 ; Номер відеофункції 2

inc dh ; Збільшити номер рядка на 1

mov dl,0 ; Стовпець = 0

int 10h ; Установити курсор на початок наступного рядка

pop ax ; Відновити номер відеофункції

; і поточний символ

continue_loop:

dec si ; Зменшити SI на 1,

; якщо він не став нулем - продовжити

jnz cloop ; CX використовується усередині циклу,

; так що не можна використовувати команду LOOP

; для його організації

ret ; Завершення Сома-файлу

Приклад 3

; dosinl. Asm

format pe

org 100h ; початок Сома-файлу

use16

start:

mov dx, messagel

mov ah,9

int 21h ; вивести запрошення до введення message1

mov dx, buffer

mov ah,0Ah

int 21h ; вважати рядок символів у буфер

mov dx, crlf

mov ah,9

int 21h ; переклад рядка

; переклад числа в ASCII-форматі з буфера в бінарне число в АХ

xor di, di ; DI = 0 - номер байта в буфері

xor ax, ax ; АХ = 0 - поточне значення результату

mov cl,[blength]

xor ch, ch

xor bx, bx

mov si, cx ; SI - довжина буфера

mov cl,10 ; CL = 10, множник для MUL

asc2hex:

mov bl, byte [bcontents+di]

sub bl,'0' ; цифра = код цифри - код символу “0”,

jb asc_error ; якщо код символу був менше, ніж код “0”,

cmp bl,9 ; або більше, ніж “9”,

ja asc_error ; вийти з програми з повідомленням про помилку,

mul cx ; інакше: помножити поточний результат на 10,

add ax, bx ; додати до нього нову цифру,

inc di ; збільшити лічильник

cmp di, si ; якщо лічильник+1 менше числа символів -

jb asc2hex ; продовжити (лічильник вважається від 0)

; вивід на екран рядка message2

push ax ; зберегти результат перетворення

mov ah,9

mov dx, message2

int 21h

pop ax

; вивід на екран числа з регістра АХ

push ax

xchg ah, al ; помістити в AL старший байт

call print_al ; вивести його на екран

pop ax ; відновити в AL молодший байт

call print_al ; вивести його на екран

ret ; завершення Сома-файлу

asc_error:

mov dx, err_msg

mov ah,9

int 21h ; вивести повідомлення про помилку

ret ; і завершити програму

; Процедура print_al

; виводить на екран число в регістрі AL

; у шестнадцатеричном форматі,

; модифікує значення регістрів АХ і DX

print_al:

mov dh, al

and dh,0Fh ; DH - молодші 4 біти

shr al,4 ; AL - старші

call print_nibble ; вивести старшу цифру

mov al, dh ; тепер AL містить молодші 4 біти

print_nibble: ; процедура виводу 4 бітів (шестнадцатеричной цифри)

cmp al,10 ; три команди, що переводять цифру в AL

sbb al,69h ; у відповідний ASCII-код

das ; (див. опис команди DAS)

mov dl, al ; код символу в DL

mov ah,2 ; номер функції DOS в АН

int 21h ; вивід символу

ret ; цей RET працює два рази - один раз

; для повернення з процедури print_nibble,

; викликаної для старшої цифри,

; і другий раз - для повернення з print_al

messagel db “Десяткове число: $"

message2 db “Шестнадцатеричное число: $"

err_msg db “Помилка введення”

crlf db 0Dh,0Ah,'$'

buffer db 6 ; максимальний розмір буфера введення

blength db ? ; розмір буфера після зчитування

bcontents: ; уміст буфера розташовується за

; кінцем Сома-файлу

Лабораторная работа №6

; multi-segment executable file template.

;linclude 'emu8086.inc'

;data segment

; add your data here!

pkey db "press any key...$"

x db 0Ch ; x=a+2b

y db ? ; y=2c-a

a1 db 30

a2 db 250

b1 db 9

b2 db 106

c1 db 7

c2 db -3

z db ? ; z=(x-y)+2

;ends

;stack segment

dw 128 dup(0)

;ends

;code segment

start:

; set segment registers:

mov ax, a1

mov ds, ax

mov es, ax

; printn "Urovnenie (R=x-y^z)"

mov ah, b1

mov bh, 2

mov al, ah

xor ah, ah

mov bl, bh

xor bh, bh

mov ch, a1

mov cl, ch

xor ch, ch

mul bx

add ax, cx

push cx

push ax

; print "x="

; call print_num

; printn

mov dl, c1

xor dh, dh

mov ax, dx

mul bx

sub ax, cx

mov bx, ax

push bx

; print "y="

; call print_num

; printn

pop bx

pop ax

mov dx, ax

sub ax, bx

add ax, 2

; print "z="

; call print_num

; printn

mov di, ax ; z

mov ax, dx

push bx ; y

; push di ; z

push ax ; x

mov dx, bx

mov ax, dx

mov cx, di

mov di, dx

dec cx

A:

mul ax

; loop [a]

mov bx, ax

; print "y^z="

;; printn

pop ax

sub ax, bx

; print "R1="

; call print_num

; printn

; ------------------------------------------------------------------ part 2

mov ah, b2

mov bh, 2

mov al, ah

xor ah, ah

mov bl, bh

xor bh, bh

mov ch, a2

mov cl, ch

xor ch, ch

mul bx

add ax, cx

push cx

push ax

; print "x="

; call print_num

; printn

mov dl, c2

xor dh, dh

mov ax, dx

mul bx

sub ax, cx

mov bx, ax

push bx

; print "y="

; call print_num

; printn

pop bx

pop ax

mov dx, ax

sub ax, bx

add ax, 2

; print "z="

; call print_num

; printn

mov di, ax ; z

mov ax, dx

push bx ; y

; push di ; z

push ax ; x

mov dx, bx

mov ax, dx

mov cx, di

mov di, dx

dec cx

B:

mul ax

; loop b

mov bx, ax

; print "y^z="

; call print_num

; printn

pop ax

sub ax, bx

; print "R2="

; call print_num

; printn

lea dx, [pkey]

mov ah, 9

int 21h ; output string at ds:dx

; wait for any key....

mov ah, 1

int 21h

mov ax, 4c00h ; exit to operating system.

int 21h

;ends

;define_scan_num

;define_print_num

;define_print_num_uns

;end start ; set entry point and stop the assembler.