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