Смекни!
smekni.com

Разработка виртуальных лабораторных работ средствами эмулятора Emu8086 (стр. 19 из 21)

jz printed

inc si

mov ah, 0eh; teletype function.

int 10h

jmp next_char

printed:

pop si; re-store registers...

pop ax;

ret

print_string endp

Данный код программы реализует перезагрузку ОС, для активации необходимо нажать F6. После этого последует сообщение о том, что надо вытащить флоппи дискету и нажать любую кнопку и тогда произойдет перезагрузка.

; +++ 'quit', 'exit', 'reboot' +++

reboot_command:

call clear_screen

leasi, Please

callprint_string

mov ax, 0; wait for any key... .

int 16h

; store magic value at 0040h: 0072h:

; 0000h - cold boot.

; 1234h - warm boot.

; mov ax, 0040h

; mov ds, ax

; mov w. [0072h], 0000h; cold boot.

; jmp 0ffffh: 0000h; reboot!

int 19h

Выводы:

Выполнив данную лабораторную работу, я изучил несколько способов перезагрузки ОС. Познал азы формирования окон на assembler'е. Узнал какие используются прерывания для BIOS.

Лабораторная работа № 4.

Конвертор из символа в ASCII код

Цель работы: Дополнить меню ОС.

Задание: Создать конвертор, обеспечивающий получить из символа ASCII код, задействуя кнопку F3.

Новые добавления:

Алгоритм конвертирования простой: пока частное не равно 0, делим его, делим и еще раз делим на 10d, запихивая остатки в стек. Потом - извлекаем из стека. Вот и вся конвертация из HEX в BIN. Это если в двух словах.

А если подробно, то вот что получается:

1 - подготавливаем делимое. Как уже говорилось, оно у нас задается неявно - обязательно через AX. А параметр у нас - через DX процедуре передается. Вот и перемещаем.

2 - это, собственно, делитель.

3 - очищаем CX. Он у нас будет в качестве счетчика.

4 - очищаем DX. Если не очистим, то мы не 1234h какое-нибудь на 10 делить будем, а 12341234h. Первое 1234 нам надо - очищать.

5 - делим. Частное - в AX, остаток - в DX.

6 - заносим остаток DX в стек.

7 - CX=CX+1. Это мы считаем сколько раз заносили остаток в стек, по кругу (прыжок на метку non_zero), пока AX не равно 0 (8). То есть делим, делим AX, пока он не окажется таким, что делить, собственно, нечего.

Деление закончено, число, которое мы поделили AX до его полного обнуления, хранится в CX.

Дальше все просто. Нам нужно такое же количество раз CX извлечь значение DX из стека. И это будет "HEX", переведенный в DEC. (Оно же: число в двоичном коде, разобранное на последовательность десятичных цифр).

Цикл, в теле которого извлечь цифру (9) и напечатать цифру (10). Столько же раз, сколько мы и делили наше исходное шестнадцатеричное число.

write_decimal proc

push ax

push cx

push dx

push bx

mov ax,dx; (1)

mov bx,10d; (2)

xor cx,cx; (3)

non_zero:

xor dx,dx; (4)

div bx; (5)

push dx; (6)

inc cx; (7)

cmp ax,0; (8)

jne non_zero

write_digit_loop:

pop dx; (9)

call write_hex_digit; (10)

loop write_digit_loop

pop bx

pop dx

pop cx

pop ax

ret

write_decimal endp

WRITE_HEX_DIGIT proc

push DX

xor dh, dh

cmp DL,0Ah

jae HEX_LETTER

add DL,30h

JMP WRITE_DIGIT

HEX_LETTER:

add DL,37h

WRITE_DIGIT:

call WRITE_CHAR

pop DX

ret

WRITE_HEX_DIGIT endp

WRITE_CHAR proc

push AX

push BX

push CX

mov AH,9

xor BH,BH

mov BL,00000111b

mov CX,1

mov AL,DL

int 10h

call CURSOR_RIGHT

pop CX

pop BX

pop AX

ret

WRITE_CHAR endp

CURSOR_RIGHT proc

push DX

call CURSOR_READ

inc DL

call CURSOR_SET

pop DX

ret

CURSOR_RIGHT endp

CURSOR_READ proc

push AX

push BX

push CX

mov AH,3

xor BH,BH

int 10h

pop CX

pop BX

pop AX

ret

CURSOR_READ endp

CURSOR_SET proc

push AX

push BX

push CX

mov AH,2

xor BH,BH

int 10h

pop CX

pop BX

pop AX

ret

CURSOR_SET endp

Выводы:

Выполнив данную лабораторную работу, я изучил алгоритм преобразования шестнадцатеричного числа в десятичное. Так как символ в регистре хранится в HEX формате.

Лабораторная работа № 5.

Динамический пароль для входа в ОС

Цель работы: Дополнить меню ОС.

Задание: Создать паролирование ОС, задействуя кнопку F2.

Новые добавления:

В меню программы есть возможность изменить текущий пароль, нажав F2. За это действие отвечает процедура changepass, которое сохраняет введенную строку в временный буфер и после чего с помощью процедуры writesec записываю в сектор.

writ db 13,10,'Write sector', 0Dh,0Ah,0

sect db 1; sector number (1. .18).

cyld db 10; cylinder number (0. .79).

head db 0; head number (0. .1).

drive db 0; drive number (0. .3); A: =0, B: =1...

BUFFERDB 512 dup (0); prosto izmenili razmer do 512

Passworddb512 dup (0)

changepass proc

push ax

push bx

push cx

push si

call clear_screen

lea si,PassMsg

call print_string

xor bx,bx

lpss:

mov ah,00h

int16h

cmpal, 13

jelConv1

mov [Password + bx], al

movah, 0eh

int10h

incbx

jmplpss

lConv1:

call writesec

call readsec; scitivau dlea proverki

lea si,BUFFER

call print_string

pop si

pop cx

pop bx

pop ax

ret

changepass ENDP

Процедура writesec обеспечивает запись данных в 10 цилиндр, в 1 сектор, с 0 головки. Заранее заполненный буфер Password, будет помещен в регистр bx для записи.

writesec proc; zapisivau dannie

push ax

push bx

push cx

push dx

lea si,writ

call print_string

wr: mov ah, 03h

mov al, 1; write 1 sector (512 bytes).

mov cl, sect; sector (1. .18)

mov ch, cyld; cylinder (0. .79)

mov dh, head; head (0. .1)

mov dl, drive; always 0 (A:)

mov bx, offset Password

mov [Password + 6],0

int 13h

jc er

jmp e2e

er: lea dx, e2

mov ah, 9

int 21h

jmp e2e

e2 db " i/o error... ",0Dh,0Ah,'$'

e2e:

pop dx

pop cx

pop bx

pop ax

ret

ENDP writesec

Процедура readsec обеспечивает считывание данных из прежних секторов в буфер BUFFER. Дальше этот буфер можно использовать в сравнение с веденным паролем или просто вывести на экран.

readsec proc; scitivau dannie

push ax

push bx

push cx

push dx

mov ah, 02h

mov al, 1; write 1 sector (512 bytes).

mov cl, sect; sector (1. .18)

mov ch, cyld; cylinder (0. .79)

mov dh, head; head (0. .1)

mov dl, drive; always 0 (A:)

mov bx, offset BUFFER

int 13h

mov [BUFFER+6],0

pop dx

pop cx

pop bx

pop ax

ret

ENDP readsec

Процедура EnterPass проводит сравнение веденного пароля с текущем зарегистрированным паролем, что записан в сектор. Сравнение происходит с помощью команды repe cmpsb. При вводе пароля предусмотрено скрывание символов под звездочкой.

EnterPassPROC

push ax

push bx

push cx

push si

xorbx, bx

lPass:

mov ah,00h; vvoju paroli

int16h

cmpal, 13

jelCompare

mov [Password + bx], al

movah, 0eh

moval, '*'

int10h

incbx

jmplPass

lCompare:

call readsec

leasi, Password

leadi, BUFFER

cld

movcx, 6

repecmpsb; sravnenie

jnelErr

jmplNext

lErr:; owibka

lea si, ENTERR

call print_string

leasi, ErrPassMsg

callprint_string

call Exit

lNext:; Paroli OK

lea si, ENTERR

call print_string

leasi, OkMsg

callprint_string

pop si

pop cx

pop bx

pop ax

; call PresKey

ret

ENDPEnterPass

; - -----------------------------------------------

Выводы:

Выполнив данную лабораторную работу, я изучил команды прерывания ввода/вывода биоса. Научился записывать на флоппи диск в определенный цилиндр и сектор. Получил опыт в сравнение двух строк.

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

Блокнот для ОС

Цель работы: Блокнот для ОС.

Задание: Создать блокнот для записи данных на флоппи диск для последующего прочтения, задействуя кнопку F1.

Новые добавления:

В данной ОС предусмотрен блокнот, он обеспечивает запись данных на флоппи диск. Для активации блокнота вам надо нажать F1. После этого последует меню самого блокнота в котором вы можете прочитать текущие данные, вести данные для записи, выйти. Запись и чтение данных происходит так же как и в 5 лабораторной работе с помощью команд биоса, только здесь задействован 11 цилиндр и 1 сектор. Данных рассчитано на 512 байт.д.анная процедура редактировать данные не может.

; - ----------------------------------------------

EditText proc

push ax

push bx

push cx

push dx

mov ah,13h

xor al,al

xor bx,bx

xor dx,dx

mov cx,menuText_len

mov bl,11

mov bp,offset menuText

mov dl,8

mov dh,18h

int 10h

mov ah,02h

mov bh,0

mov dh,2

mov dl,1

int 10h

AgainTe:

mov ah,00h

int 16h

cmp al,0

jne AgainTe

cmp ah,3Ch; Pres F2?

je F2t

cmp ah,3Dh; Pres F3?

je F3t

cmp ah,3Eh; Pres F4?

je F4t

jmp AgainTe

F2t:

jmp readtext

F3t:

call clear_screen

jmp writetext

F4t:

call clear_screen

jmp the_end

writetext:

mov ah,13h

xor al,al

xor bx,bx

xor dx,dx

mov cx,menuText_len

mov bl,11

mov bp,offset menuText

mov dl,8

mov dh,18h

int 10h

mov ah,02h

mov bh,0

mov dh,2

mov dl,1

int 10h

xor bx,bx

lp:

mov ah,00h

int16h

cmp ah,3Bh

jelC

cmpah,3Eh

jeF4t

mov [Editor + bx], al

movah, 0eh

int10h

incbx

jmplp

lC:

mov ah, 03h

mov al, 1; write 1 sector (512 bytes).

mov cl, sect; sector (1. .18)

mov ch, 11; cylinder (0. .79)

mov dh, head; head (0. .1)

mov dl, drive; always 0 (A:)

mov bx, offset Editor

int 13h

jmp the_end

readtext:

mov ah, 02h

mov al, 1; write 1 sector (512 bytes).

mov cl, sect; sector (1. .18)

mov ch, 11; cylinder (0. .79)

mov dh, head; head (0. .1)

mov dl, drive; always 0 (A:)

mov bx, offset BUFFER

int 13h

mov [BUFFER+512],0

call clear_screen

lea si,BUFFER

call print_string

mov ah,13h

xor al,al

xor bx,bx

xor dx,dx

mov cx,menuText_len

mov bl,11

mov bp,offset menuText

mov dl,8

mov dh,18h

int 10h

mov ah,02h

mov bh,0

mov dh,2

mov dl,1

int 10h

jmp AgainTe

the_end:

pop dx

pop cx

pop bx

pop ax

ret

endp EditText

Код программы ОС:

. model small

CSEG segment

assume cs: CSEG, ds: CSEG, es: CSEG, ss: CSEG

; - --------------------------------------------- -

Start:

jmp EndData

mes1DB13,10,' Pres <F1>', 0Dh,0Ah,0

mes2DB13,10,'PASSS is... ', 0Dh,0Ah,0

writ db 13,10,'Write sector', 0Dh,0Ah,0

sect db 1; sector number (1. .18).

cyld db 10; cylinder number (0. .79).

head db 0; head number (0. .1).

drive db 0; drive number (0. .3); A: =0, B: =1...

BUFFERDB 512 dup (0); prosto izmenili razmer do 512

Passworddb512 dup (0)

EditorDB512 dup (0)

PassMsgdb13,10,'Enter password: ', 0Dh,0Ah,0

OkMsgdb13,10,' - > OK', 0Dh,0Ah,0

ErrPassMsg db13,10,'Password incorrect', 0Dh,0Ah,0

ConvEnterSy db13,10,' Convertor symbol in ASCII v1.0', 0Dh,0Ah

db13,10,'Enter symbol: ',0

ConResultAdb' Result ASCII: ',0

string db " Operatsionnaea Sistema studenta Macarova Anatoliea, grupa TI-065"

string_len equ $-string

menuText DB"F1 Save F2 Read F3 New Write F4 Close "

menuText_len equ $-menuText

menu DB"F1 Bloknot F2 Change PAss F3 Convertor F4 ClearScreen F5 About F6 Exit"

menu_len equ $-menu

About DB 13,10

db ' +------------------------------------------------+', 0Dh,0Ah

db ' |XXXXXXXXXXXXXXXX About Makar OS XXXXXXXXXXXXXXXX|', 0Dh,0Ah

db ' +------------------------------------------------|', 0Dh,0Ah

db ' | |', 0Dh,0Ah

db ' | +----------------------------------------+ |', 0Dh,0Ah

db ' | | | |', 0Dh,0Ah

db ' | | @@@@ Makar OS A 1.5 | |', 0Dh,0Ah

db ' | | @@@@ | |', 0Dh,0Ah

db ' | | Copiright (C) 2008 | |', 0Dh,0Ah

db ' | | Author Macarov Anatoli TI-065 | |', 0Dh,0Ah

db ' | | All Rights Reserved | |', 0Dh,0Ah

db ' | +----------------------------------------+ |', 0Dh,0Ah

db ' | |', 0Dh,0Ah

db ' | +-----------+ |', 0Dh,0Ah

db ' | |####OK#####| |', 0Dh,0Ah

db ' | +-----------+ |', 0Dh,0Ah

db ' +------------------------------------------------+', 0Dh,0Ah,0

About_len equ $-About

Please db 13,10," please eject any floppy disks "

db 13,10," and press any key to reboot... ",0

ENTERR db 13,10,"",0

EndData:

mov ax,cs

mov es,ax

mov ds,ax

xor di,di

xor si,si

xor dx,dx

xor bx,bx

xor cx,cx

mov ss,ax

mov sp,0FFFEh

; blinking disabled for compatibility with dos/bios,

; emulator and windows prompt never blink.

mov ax, 1003h

mov bx, 0; disable blinking.

int 10h

leasi, PassMsg

callprint_string

callEnterPass

call clear_screen

call PresKey

Exit:

mov ah,00h

int 16h

hlt

; - -----------------------------------------------

PresKeyPROC

Again:

mov ah,00h

int 16h