-
Notifications
You must be signed in to change notification settings - Fork 0
/
kernel.asm
153 lines (132 loc) · 3.03 KB
/
kernel.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
;kernel.asm
;kernel.asm contains assembly functions that you can use in your kernel
.global _putInMemory
.global _interrupt
.global _makeInterrupt21
.global _launchProgram
.extern _handleInterrupt21
.global _printhex
;void putInMemory (int segment, int address, char character)
_putInMemory:
push bp
mov bp,sp
push ds
mov ax,[bp+4]
mov si,[bp+6]
mov cl,[bp+8]
mov ds,ax
mov [si],cl
pop ds
pop bp
ret
;int interrupt (int number, int AX, int BX, int CX, int DX)
_interrupt:
push bp
mov bp,sp
mov ax,[bp+4] ;get the interrupt number in AL
push ds ;use self-modifying code to call the right interrupt
mov bx,cs
mov ds,bx
mov si,#intr
mov [si+1],al ;change the 00 below to the contents of AL
pop ds
mov ax,[bp+6] ;get the other parameters AX, BX, CX, and DX
mov bx,[bp+8]
mov cx,[bp+10]
mov dx,[bp+12]
intr: int #0x00 ;call the interrupt (00 will be changed above)
mov ah,#0 ;we only want AL returned
pop bp
ret
;void makeInterrupt21()
;this sets up the interrupt 0x21 vector
;when an interrupt 0x21 is called in the future,
;_interrupt21ServiceRoutine will run
_makeInterrupt21:
;get the address of the service routine
mov dx,#_interrupt21ServiceRoutine
push ds
mov ax, #0 ;interrupts are in lowest memory
mov ds,ax
mov si,#0x84 ;interrupt 0x21 vector (21 * 4 = 84)
mov ax,cs ;have interrupt go to the current segment
mov [si+2],ax
mov [si],dx ;set up our vector
pop ds
ret
;this is called when interrupt 21 happens
;it will call your function:
;void handleInterrupt21 (int AX, int BX, int CX, int DX)
_interrupt21ServiceRoutine:
push dx
push cx
push bx
push ax
call _handleInterrupt21
pop ax
pop bx
pop cx
pop dx
iret
;this is called to start a program that is loaded into memory
;void launchProgram(int segment)
_launchProgram:
mov bp,sp
mov bx,[bp+2] ;get the segment into bx
mov ax,cs ;modify the jmp below to jump to our segment
mov ds,ax ;this is self-modifying code
mov si,#jump
mov [si+3],bx ;change the first 0000 to the segment
mov ds,bx ;set up the segment registers
mov ss,bx
mov es,bx
mov sp,#0xfff0 ;set up the stack pointer
mov bp,#0xfff0
jump: jmp #0x0000:0x0000 ;and start running (the first 0000 is changed above)
;printhex is used for debugging only
;it prints out the contents of ax in hexadecimal
_printhex:
push bx
push ax
push ax
push ax
push ax
mov al,ah
mov ah,#0xe
mov bx,#7
shr al,#4
and al,#0xf
cmp al,#0xa
jb ph1
add al,#0x7
ph1: add al,#0x30
int 0x10
pop ax
mov al,ah
mov ah,#0xe
and al,#0xf
cmp al,#0xa
jb ph2
add al,#0x7
ph2: add al,#0x30
int 0x10
pop ax
mov ah,#0xe
shr al,#4
and al,#0xf
cmp al,#0xa
jb ph3
add al,#0x7
ph3: add al,#0x30
int 0x10
pop ax
mov ah,#0xe
and al,#0xf
cmp al,#0xa
jb ph4
add al,#0x7
ph4: add al,#0x30
int 0x10
pop ax
pop bx
ret