Documente Academic
Documente Profesional
Documente Cultură
RAPORT
Lucrare de laborator Nr.4
la Sisteme de operare: mecanisme interne i
principii de proiectare
Tema: Dezvoltarea nucleului i adugarea de funcionaliti
A efectuat:
st. gr.
SI-141
Ecate
rina Nemerenco
A verificat:
lect. asistent
Sergiu Ciudin
Chiinu 2016
Mersul lucrari:
Pentru efectuarea acestei lucrri de laborator avem nevoie s nsuim
ntreruperile BIOS i s le utilizm mpreun cu limbajul assembler pentru a putea
efectua sarcina propus.
n cadrul laboratorului am utilizat ntreruperile:
-
Bootloaderul
Loading
Kernel-ul
Kernelul sistemului este plasat pe sectorul 4 al discului, aici are loc toate
activitile principale, precum deschiderea meniului(Figura 2), executarea anumitor
funcii, etc. Dup condiia noastr sistemul de operare trebuie s conin
urmtoarele funcii: System Info, Beep, Draw, Calculator, Time, About. Kernelul
este i nucleul sistemului de operare, el conine meniul, i celelalte funcii, dar i
apeluri spre poriunile de memorie care conin anumite funcii.
Figura 2 Kernel-ul
n figura dat se poate observa meniul sistemului de operare, care con ine
denumirea sistemului de operare, meniul acestuia dar i butoanele ce pot fi
accesate pentru a dirija cu sistemul de operare. Pentru navigarea n meniu se
folosesc butoanele UP i DOWN, butonul ENTER selecteaz funcia aleas, iar
butonul ESC restarteaz sistemul. Pentru utilizarea acestor funcii am folosit un
contor, i n dependen de meniul selectat se execut i se coloreaz opiunea
selectat, iar la micare prin meniu se incrimenteaz sau se decrementeaz contorul
i se mic meniul.
Primul punct din meniu reprezint System Info(Figura 3). Acest punct
afieaz la ecran informaia despre sistem, iar aceasta se face dup selectarea
punctului dat din meniu, i n caz cnd este apsat tasta Enter are loc saltul la
funcia de afiare a informaiei despre sistem.
include 'emu8086.inc'
DEFINE_PRINT_NUM_UNS
mov ah, 88h
int 15h
call PRINT_NUM_UNS
Figura 4 Beep
n figura dat se poate observa n centrul ecranului un text ce arat c
sunetele sunt redate, iar dup ce sunt redate toate sunetele n colul dreapta jos
apare mesajul de apsare a butonului ESC pentru a reveni la meniul principal.
mov dl, 07h
mov ah, 2
int 21h
cx,
dx,
al,
mov
10h
100
150
11
ah, 0ch
;
;
;
;
coloana
rindul
culoare
afisam pixel
dec dx
cmp dx, 50
jae u1
Figura 7 Calculator
n figura dat este afiat aplicaia calculatorului. Ea este apelat din blocul
de memorile cu numrul 17, i este nregistrat pe 2 sectoare. Acest calculator
citete de la tastatur 2 numere cu ajutorul funciei SCAN_NUM. Aceste numere
sunt nregistrate n variabile aparte. Pentru citirea semnului se verific operatorul
primit de la tastatur, n caz c un corespunde, este afi at un mesaj de eroare i
revine la meniul pincipal. Dup primirea datelor necesare are loc verificarea
operatorului care a fost introdus i executarea instruciunilor cuvenite.
; calculate:
cmp opr, '+'
je do_plus
cmp opr, '-'
je do_minus
cmp opr, '*'
je do_mult
cmp opr, '/'
je do_div
Figura 8 Time
n figura dat este afiat ora sistemului, ea este citit din BIOS, i este
afiat la ecran n formatul HH:MM:SS. La accesarea orei din meniu are loc
afiarea orei pentru cteva secunde, apoi are loc ntoarcerea la meniul principal.
Ora este citit cu ajutorul instruciunii 1ah, i n regitrii ch, cl, dh sunt nscrise ora,
minute, secunde, i are loc afiarea acestora la ecran. Ora este rennoit instant
timp de cteva secunde pn la revenirea n meniul principal.
inc count
mov ah, 02h
int 1ah
mov al, ch
call deci
mov word ptr hour, ax
mov al, cl
call deci
mov word ptr minu, ax
mov al, dh
call deci
mov word ptr seco, ax
;
;
;
;
"cerem" timpul
transformind din hexa
in decimal
ore
;
; minute
;
;
; secunde
;
;
Al 6-lea punct din meniu este punctul About(Figura 9). Aici este afi at
informaia despre sistemul de operare.
Figura 9 About
n fereastra precedent se observ creatorul sistemei de operare iar mai jos
un mesaj ce indic c la apsarea tastei ESC are loc ntoarcerea n Meniu principal.
Mesajul este afiat cu ajutorul funciei de afiare a mesajelor text.
Concluzie
n urma efecturii acestei lucrri de laborator am studiat metodele de
reprezentare a ncrcrii sistemului utiliznd interfeele UI, am creat propriul
Kernel i propriul sistem de operare cu anumite funcii. Am utilizat func ii
principare ca funcia de citire a timpului din Bios, citire a memoriei RAM,
detectare a procesorului, utilizare a dispozitivelor grafice pentru a reprezenta
anumite figuri. n urma utilizrii acestora am creat cu succes un mic sistem de
operare, care are fereastr de ncrcare, anumite funci, printre care sunt nscrise pe
sectoare diferite.
#make_boot#
Anexa A
Bootloader.asm
org 07c00h
;=================kernel==================
push es
mov bx, 6000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 2
; number of sectors to read
mov ch, 0
; track number
mov cl, 2
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jmp 6000h:0000h ; jump to kernel
db 510-($-start) dup(0)
dw 0AA55h
Loading.asm
xor ax,ax
; ax=0
mov ax, 107h
int 10h
mov ch,32
; hide cursor
mov ah,1
; set cursor
int 10h
call ClrScr
jmp start
;=============Text Macro================
writeMessage macro message,x,y,color,size
pusha
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
popa
endm
;===============Progress bar============
Cell:
pusha
mov ah,02h
int 10h
mov al,219
mov ah,09h
mov cx,1
int 10h
popa
ret
;==========Delay Macro==================
Sleep:
mov ah,86h
mov cx,3
int 15h
ret
;=============Clear Screen proc=========
ClrScr:
pusha
mov dx,0000h
mov ax,0200h ; seteaza cursorul
int 10h
mov bx,0000h ;culoare fundalului
mov ax,09DBh
mov cx,4000
int 10h
popa
ret
;===============Progress Bar============
start:
; 1
mov bl,0010b
mov dh,16
mov dl,25
call Cell
call Sleep
; 2
mov dh,16
mov dl,27
call Cell
;===Ram Check======
mov ah, 88h
int 15h
cmp ax,10240
jb noRam
call Sleep
; 3
mov dh,16
mov dl,29
call Cell
call Sleep
; 4
mov dh,16
mov dl,31
call Cell
call Sleep
; 5
mov dh,16
mov dl,33
call Cell
call Sleep
; 6
mov bl,1110b
mov dh,16
mov dl,35
call Cell
call Sleep
; 7
mov dh,16
mov dl,37
call Cell
call Sleep
; 8
mov dh,16
mov dl,39
call Cell
call Sleep
; 9
mov dh,16
mov dl,41
call Cell
call Sleep
; 10
mov dh,16
mov dl,43
call Cell
call Sleep
; 11
mov bl,1100b
mov dh,16
mov dl,45
call Cell
call Sleep
; 12
mov dh,16
mov dl,47
call Cell
call Sleep
; 13
mov dh,16
mov dl,49
call Cell
call Sleep
; 14
mov dh,16
mov dl,51
call Cell
call Sleep
; 15
mov bl,0100b
mov dh,16
mov dl,53
call Cell
call Sleep
;=================kernel==================
push es
mov bx, 2000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 6
; number of sectors to read
mov ch, 0
; track number
mov cl, 4
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jc noFloppy
jmp 2000h:0000 ; jump to kernel
noRam:
call ClrScr
db
db
db
Kernel.asm
org 0000h
mov dl,10
mov pas,dl
call ClrScr
jmp Start
;=============Clear Screen proc=========
ClrScr:
pusha
mov dx,0000h
mov ax,0200h ; seteaza cursorul
int 10h
mov bx,0000h ;culoare fundalului
mov ax,09DBh
mov cx,4000
int 10h
popa
ret
;===========Message Macro===============
writeMessage macro message,x,y,color,size
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
endm
;===========Wait========================
wait06:
mov ah,86h
mov cx,0x0009
int 15h
ret
;===========Beep========================
beep_sound:
PROC near
AX
DS
BX
CX
DI
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
DEC
INT
AX,
DS,
AH,
AL,
BH,
CH,
CL,
DI,
DH,
DI,
DL,
DL
10h
40h
;
AX
;
06h
;
0
;
000_0111b ;
0
;
0
;
84h
;
[DI]
;
4Ah
;
[DI]
;
;
MOV
MOV
MOV
MOV
INT
BH,
DL,
DH,
AH,
10h
0
0
0
02
POP
POP
POP
POP
POP
DI
CX
BX
DS
AX
RET
CLEAR_SCREEN ENDP
;=========================================================
;=========================DataSegement================
UP
EQU
48h
DOWN
EQU
50h
pas
db 10
;-------Menu------
menu1
menu2
menu3
db
db
db
;-------Labels---label1
db
'- SYSTEM INFORMATION'
label2
db
'- BEEP'
;6
label3
db
'- DRAW'
;6
label4
db
'- CALCULATOR'
;10
label5
db
'- TIME'
;4
label6
db
'- ABOUT'
;5
label7
label8
label9
label10
label11
label12
label13
db
db
db
db
db
db
db
'Press'
'ENTER'
'ESC'
'UP/DOWN'
'to select'
'to restart'
'to move'
esc
db
about1
about2
about3
db
db
db
'Catarina-OS'
;8
'Created by'
;10
'Ecaterina Nemerenco';19
;5
;5
;3
;7
;9
;10
;7
beep_play db
'Playing.....'
draw1
draw2
draw3
draw4
db
db
db
db
'Select triangle';15
'1 rectangular' ;13
'2 obtuse'
;8
'3 acute-angled' ;14
time_text
time_disp
count
hour
min
sec
dw
dw
db
dw
dw
dw
sysinfo1
sysinfo2
sysinfo2_1
sysinfo3
sysinfo3_1
sysinfo4
;12
;18
'System info'
'System:'
'NasteaOS V1.0'
'CPU:'
'----'
'RAM:
'
;16
;8
;11
;7
;13
;4
;3
;4
key_wait:
mov ah,00h
int 16h
cmp al,27
je Start
jne key_wait
sys_info:
call CLEAR_SCREEN
;======System info=======
writeMessage sysinfo1,
35, 8,0010b,11
writeMessage sysinfo2,
30,11,1110b,7
writeMessage sysinfo2_1, 38,11,0111b,13
writeMessage sysinfo3,
30,12,1110b,4
writeMessage sysinfo3_1 38,12,0111b,4
;42
writeMessage sysinfo4,
30,13,1110b,8
include 'emu8086.inc'
DEFINE_PRINT_NUM_UNS
mov ah, 88h
int 15h
call PRINT_NUM_UNS
writeMessage esc,60,24,1111b,19
;========================
jmp key_wait
beep:
call ClrScr
;======Beep =============
writeMessage beep_play, 29,10,0101b,12
call beep_sound
call beep_sound
call wait06
call beep_sound
call beep_sound
call wait06
call beep_sound
call wait06
call beep_sound
call beep_sound
call beep_sound
call beep_sound
call wait06
call beep_sound
call beep_sound
call beep_sound
call wait06
writeMessage esc,60,24,1111b,19
;========================
jmp key_wait
draw:
;=====Draw===============
Start_drawing:
call ClrScr
mov ch,32
; hide cursor
mov ah,1
; set cursor
int 10h
;=====Draw menu==========
writeMessage draw1, 30,8 ,1001b,15
writeMessage draw2, 30,10,1110b,13
writeMessage draw3, 30,11,1110b,8
writeMessage draw4, 30,12,1110b,14
writeMessage esc,
30,14,1111b,19
draw_key:
mov ah,00h
int 16h
cmp al,49
je tr_dr
cmp al,50
je tr_ob
cmp al,51
je tr_as
cmp al,27
je Start
jne draw_key
;========================
tr_dr:
; triunghi dreptunghic
call ClrScr
mov ah, 0
mov al, 13h
int 10h
mov cx, 100
; coloana
mov dx, 150
; rindul
mov al, 11
; culoare
u1: mov ah, 0ch
; afisam pixel
int 10h
dec dx
cmp dx, 50
jae u1
mov cx, 200
; coloana
mov dx, 150
; rindul
mov al, 11
; culoare
u2: mov ah, 0ch
; afisam pixel
int 10h
dec cx
cmp cx, 100
jae u2
mov cx, 200
; coloana
mov dx, 150
; rindul
mov al, 11
; culoare
u3: mov ah, 0ch
; afisam pixel
int 10h
dec
dec
cmp
jae
dx
cx
dx, 50
u3
writeMessage esc,
wait_key1:
mov ah,00h
int 16h
cmp al,27
je Stop_drawing
jne wait_key1
20,24,1111b,19
tr_ob:
; triunghi obtuz
call ClrScr
mov ah, 0
mov al, 13h
int 10h
mov cx, 150
; coloana
mov dx, 120
; rindul
mov al, 14
; culoare
u4: mov ah, 0ch
; afisam pixel
int 10h
dec
dec
dec
cmp
jae
dx
cx
cx
cx, 50
u4
dx
cx
cx
cx, 250
u5
mov cx, 50
; coloana
mov dx, 70
; rindul
mov al, 14
; culoare
u6: mov ah, 0ch
; afisam pixel
int 10h
inc cx
cmp cx, 250
jbe u6
writeMessage esc,
20,24,1111b,19
wait_key2:
mov ah,00h
int 16h
cmp al,27
je Stop_drawing
jne wait_key2
tr_as:
; triungi ascutit
call ClrScr
mov ah, 0
mov al, 13h
int 10h
mov cx, 50
; coloana
mov dx, 150
; rindul
mov al, 13
; culoare
u7: mov ah, 0ch
; afisam pixel
int 10h
dec
inc
inc
cmp
jbe
dx
cx
cx
cx, 250
u7
dec
inc
cmp
jbe
dx
cx
cx, 250
u8
mov cx, 50
; coloana
mov dx, 150
; rindul
mov al, 13
; culoare
u9: mov ah, 0ch
; afisam pixel
int 10h
inc cx
cmp cx, 150
jbe u9
writeMessage esc,
20,24,1111b,19
wait_key3:
mov ah,00h
int 16h
cmp al,27
je Stop_drawing
jne wait_key3
Stop_drawing:
mov ah,00
mov al,03
int 10h
mov
mov
int
jmp
;
; intoarcem la text mode
;
ax, 1003h
; scoatem clipirea
bx, 0
; textului
10h
;
Start_drawing
;========================
jmp key_wait
calculator:
;call ClrScr
;=====Calculator=========
push es
mov bx, 1000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 2
; number of sectors to read
mov ch, 0
; track number
mov cl, 16
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jmp 1000h:0000h ; jump to kernel
;========================
jmp key_wait
time:
call ClrScr
;=====Time===============
push es
mov bx, 1000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 1
; number of sectors to read
mov ch, 0
; track number
mov cl, 15
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jmp 1000h:0000h ; jump to kernel
;========================
about:
call ClrScr
;=====About==============
writeMessage about1, 31,10,1010b,8
writeMessage about2, 30,12,1110b,10
writeMessage about3, 28,13,1110b,19
writeMessage esc,
60,24,1111b,19
;========================
jmp key_wait
RebotSystem:
int 19h
MoveDOWN:
cmp pas,20
je nimicDOWN
mov dl, pas
inc dl
inc dl
mov pas, dl
nimicDOWN:
jmp menu
MoveUP:
cmp pas,10
je nimicUP
mov dl, pas
dec dl
dec dl
mov pas, dl
nimicUP:
jmp menu
Enter_pressed:
cmp pas,10
je sys_info
cmp pas,12
je beep
cmp pas,14
je draw
cmp pas,16
je calculator
cmp pas,18
je time
cmp pas,20
je about
call ClrScr
jmp Start
Start:
mov ch,32
; hide cursor
mov ah,1
int 10h
call ClrScr
; set cursor
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
menu1,20,5, 1111b,42
menu2,20,6, 1111b,42
menu2,20,7,1111b,42
menu2,20,8,1111b,42
menu2,20,9,1111b,42
menu2,20,10,1111b,42
menu2,20,11,1111b,42
menu2,20,12,1111b,42
menu2,20,13,1111b,42
menu2,20,14,1111b,42
menu2,20,15,1111b,42
menu2,20,16,1111b,42
menu2,20,17,1111b,42
menu2,20,18,1111b,42
menu3,20,19,1111b,42
next3:
cmp pas,16
je label4_t
jne label4_f
label4_t:
writeMessage label4,30,13,1100b,12
jmp next4
label4_f:
writeMessage label4,30,13,1110b,12
jmp next4
next4:
cmp pas,18
je label5_t
jne label5_f
label5_t:
writeMessage label5,30,15,1100b,6
jmp next5
label5_f:
writeMessage label5,30,15,1110b,6
jmp next5
next5:
cmp pas,20
je label6_t
jne label6_f
label6_t:
writeMessage label6,30,17,1100b,7
jmp wait_for_key_press
label6_f:
writeMessage label6,30,17,1110b,7
jmp wait_for_key_press
wait_for_key_press:
mov ah,00h
int 16h
cmp ah,DOWN
je moveDOWN
cmp ah,UP
je moveUP
cmp al,27
je RebotSystem
cmp al,13
je Enter_pressed
jne wait_for_key_press
Time.asm
org 0000h
mov count,0
mov ch,32
mov ah,1
int 10h
; scotem clipirea
; textului
jmp start
hour
minu
seco
count
db
db
db
db
0, 0, ':'
0, 0, ':'
0, 0, 0
0
; ore
; minute
; secunde ceasului
start:
push
pop
cs
ds
mov
mov
int
ah, 00h
al, 03h
10h
deseneaza_timpul:
mov ch,32
mov ah,1
int 10h
; scotem clipirea
; textului
inc count
mov ah, 02h
int 1ah
mov al, ch
call deci
mov word ptr hour, ax
mov al, cl
call deci
mov word ptr minu, ax
mov al, dh
call deci
mov word ptr seco, ax
mov
mov
mov
mov
int
ah,2
bh,0
dl,27h-4
dh,0ch
10h
lea
call
si, hour
print_string ;
;
;
;
;
"cerem" timpul
transformind din hexa
in decimal
ore
;
; minute
;
;
; secunde
;
;
; pozitionam
; la centrul
; ecranului
;
;
; afisam
call wait06
cmp count,20
je Stop
jmp deseneaza_timpul
print_string proc near
push
push
ax
si
next_char:
mov
al, [si]
cmp
al, 0
jz printed
;
inc
si
mov
ah, 0eh
int
10h
jmp
next_char
printed:
pop
si
pop
ax
ret
print_string endp
; restabilim registre
;
deci:
push cx
xor ah, ah
mov cl, 16
div cl
add ax, 3030h
pop cx
ret
; functia de transformare
; din hexazecimal in decimal
;
;
;
;
;
;
wait06:
mov ah,86h
mov cx,0x0009
int 15h
ret
Stop:
push es
mov bx, 2000h
mov es, bx
mov bx, 0
mov ah, 2
mov al, 6
mov ch, 0
mov cl, 4
mov dh, 0
mov dl, 0
int 13h
jmp 2000h:0000
;
;
;
;
;
;
;
;
;
;
;
ES:BX = 1000:000
es is 1000h now
bx is 0 now
load disk data into ES:BX, read sectors
number of sectors to read
track number
sector number (kernel is in the second sector)
head number
drive number
call BIOS
jump to kernel
Calculator.asm
jmp start
;========================================================
CLEAR_SCREEN
PUSH
PUSH
PUSH
PUSH
PUSH
PROC near
AX
DS
BX
CX
DI
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
DEC
INT
AX,
DS,
AH,
AL,
BH,
CH,
CL,
DI,
DH,
DI,
DL,
DL
10h
MOV
MOV
BH, 0
DL, 0
40h
;
AX
;
06h
;
0
;
000_0111b ;
0
;
0
;
84h
;
[DI]
;
4Ah
;
[DI]
;
;
MOV
MOV
INT
DH, 0
AH, 02
10h
;
;
;
POP
POP
POP
POP
POP
DI
CX
BX
DS
AX
; restabilim registii
;
;
;
;
RET
CLEAR_SCREEN ENDP
;==============================================
writeMessage macro message,x,y,color,size
pusha
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
popa
endm
;===============================================
PUTC
MACRO
char
PUSH
AX
MOV
AL, char
MOV
AH, 0Eh
INT
10h
POP
AX
ENDM
; define variables:
msg0
msg1
msg2
msg3
msg4
msg5
err1
smth
db
db
db
db
db
db
db
db
'Calculator'
'Enter 1 number: '
'Enter operator(+,-,*,/): '
'Enter 2 number: '
'Result: '
'Press any key to return...'
'Wrong operator!'
'and something...'
opr db '?'
; + - * / q
num1 dw ?
num2 dw ?
start:
call CLEAR_SCREEN
writeMessage msg0, 35, 3, 0011b,10
writeMessage msg1, 25, 5, 0111b,16
call scan_num
;10
;16
;25
;16
;8
;26
;15
;16
mov num1, cx
writeMessage msg2, 25, 6, 0111b, 25
; get operator:
mov ah, 10h
; single char input to AL.
int 16h
mov opr, al
putc al
cmp opr, 'q'
je exit
2000h
bx
0
2
6
0
4
0
0
;
;
;
;
;
;
;
;
;
;
ES:BX = 1000:000
es is 1000h now
bx is 0 now
load disk data into ES:BX, read sectors
number of sectors to read
track number
sector number (kernel is in the second sector)
head number
drive number
call BIOS
jmp 2000h:0000
; jump to kernel
do_plus:
mov ax, num1
add ax, num2
call print_num
jmp exit
do_minus:
mov ax, num1
sub ax, num2
call print_num
jmp exit
; print ax value.
; print ax value.
do_mult:
mov ax, num1
imul num2 ; (dx ax) = ax * num2.
call print_num
; print ax value.
; dx is ignored (calc works with tiny numbers only).
jmp exit
do_div:
; dx is ignored (calc works with tiny integer numbers only).
mov dx, 0
mov ax, num1
idiv num2 ; ax = (dx ax) / num2.
cmp dx, 0
jnz approx
call print_num
; print ax value.
jmp exit
approx:
call print_num
; print ax value.
writeMessage smth, 36,8,0111b,16
jmp exit
; gets the multi-digit SIGNED number from the keyboard,
; and stores the result in CX register:
SCAN_NUM
PROC
NEAR
PUSH
DX
PUSH
AX
PUSH
SI
MOV
CX, 0
; reset flag:
MOV
CS:make_minus, 0
next_digit:
; get char from keyboard
; into AL:
MOV
AH, 00h
INT
16h
; and print it:
MOV
AH, 0Eh
INT
10h
; check for MINUS:
CMP
AL, '-'
JE
set_minus
; check for ENTER key:
CMP
AL, 0Dh ; carriage return?
JNE
JMP
not_cr
stop_input
CMP
JNE
MOV
MOV
DIV
MOV
PUTC
PUTC
JMP
AL, 8
backspace_checked
DX, 0
AX, CX
CS:ten
CX, AX
' '
8
next_digit
not_cr:
; 'BACKSPACE' pressed?
; remove last digit by
; division:
; AX = DX:AX / 10 (DX-rem).
; clear position.
; backspace again.
backspace_checked:
; allow only digits:
CMP
AL, '0'
JAE
ok_AE_0
JMP
remove_not_digit
ok_AE_0:
CMP
AL, '9'
JBE
ok_digit
remove_not_digit:
PUTC
8
; backspace.
PUTC
' '
; clear last entered not digit.
PUTC
8
; backspace again.
JMP
next_digit ; wait for next input.
ok_digit:
; multiply CX by 10 (first time the result is zero)
PUSH
AX
MOV
AX, CX
MUL
CS:ten
; DX:AX = AX*10
MOV
CX, AX
POP
AX
; check if the number is too big
; (result should be 16 bits)
CMP
DX, 0
JNE
too_big
; convert from ASCII code:
SUB
AL, 30h
; add AL to CX:
MOV
AH, 0
MOV
DX, CX
ADD
CX, AX
JC
too_big2
JMP
set_minus:
MOV
JMP
too_big2:
MOV
MOV
too_big:
MOV
DIV
MOV
next_digit
CS:make_minus, 1
next_digit
CX, DX
DX, 0
AX, CX
CS:ten
CX, AX
PUTC
PUTC
PUTC
JMP
stop_input:
; check
CMP
JE
NEG
not_minus:
POP
POP
POP
RET
make_minus
SCAN_NUM
8
; backspace.
' '
; clear last entered digit.
8
; backspace again.
next_digit ; wait for Enter/Backspace.
flag:
CS:make_minus, 0
not_minus
CX
SI
AX
DX
DB
ENDP
; used as a flag.
AX, 0
not_zero
PUTC
JMP
'0'
printed
not_zero:
; the check SIGN of AX,
; make absolute if it's negative:
CMP
AX, 0
JNS
positive
NEG
AX
PUTC
positive:
CALL
printed:
POP
POP
RET
PRINT_NUM
'-'
PRINT_NUM_UNS
AX
DX
ENDP
MOV
BX, 10000
; 2710h - divider.
; AX is zero?
CMP
AX, 0
JZ
print_zero
begin_print:
; check divider (if zero go to end_print):
CMP
BX,0
JZ
end_print
; avoid printing zeros before number:
CMP
CX, 0
JE
calc
; if AX<BX then result of DIV will be zero:
CMP
AX, BX
JB
skip
calc:
MOV
CX, 0
; set flag.
MOV
DIV
DX, 0
BX
; AX = DX:AX / BX
; print
; AH is
ADD
PUTC
last digit
always ZERO, so it's ignored
AL, 30h
; convert to ASCII code.
AL
MOV
AX, DX
(DX=remainder).
skip:
; calculate BX=BX/10
PUSH
AX
MOV
DX, 0
MOV
AX, BX
DIV
CS:ten ; AX = DX:AX / 10
MOV
BX, AX
POP
AX
JMP
print_zero:
PUTC
(DX=remainder).
begin_print
'0'
end_print:
POP
POP
POP
POP
RET
PRINT_NUM_UNS
DX
CX
BX
AX
ENDP
ten
PRINT_NUM_UNS.
GET_STRING
PUSH
AX
PUSH
CX
PUSH
DI
DW
PROC
10
NEAR
PUSH
DX
MOV
CX, 0
; char counter.
CMP
JBE
DX, 1
empty_buffer
DEC
DX
;============================
; Eternal loop to get
; and processes key presses:
wait_for_key:
MOV
INT
AH, 0
16h
CMP
JZ
AL, 0Dh
exit_GET_STRING
CMP
JNE
JCXZ
DEC
DEC
PUTC
PUTC
PUTC
JMP
AL, 8
add_to_buffer
wait_for_key
CX
DI
8
' '
8
wait_for_key
; 'RETURN' pressed?
; 'BACKSPACE' pressed?
; nothing to remove!
; backspace.
; clear position.
; backspace again.
add_to_buffer:
CMP
JAE
CX, DX
wait_for_key
MOV
INC
INC
[DI], AL
DI
CX
ENDP
; buffer is full?
; if so wait for 'BACKSPACE' or 'RETURN'...