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
|
.global int0
.global int1
.global int2
.global int3
.global int4
.global int5
.global int6
.global int7
.global int8
.global int9
.global int10
.global int11
.global int12
.global int13
.global int14
.global int15
.global int128
// nothing to ack
.macro ack0
.endm
// ack master
.macro ack1
push %eax // persist
mov $0x20,%al
out %al,$0x20
pop %eax // load original
.endm
// ack master and servant
.macro ack2
push %eax // persist
mov $0x20,%al
out %al,$0xa0 // slave
out %al,$0x20 // master
pop %eax // load original
.endm
.macro intx ack num func
\ack
pusha //Push all standard registers 8 regs x 4bytes/32bit
push %ds //Push data segment
push %es //etc...
push %fs
push %gs
mov %esp,%eax
and $-16,%esp // padding to align stack on 16byte boundary before CALL
push \num
push \num
push \num
push %eax // pass in original %esp
call \func
mov %eax,%esp // use %esp we got
pop %gs
pop %fs
pop %es
pop %ds
popa
iret // pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack
.endm
int0: intx ack1 $0 pit_handler
int1: intx ack1 $1 kb_handler
int2: intx ack1 $2 interrupt_handler
int3: intx ack1 $3 interrupt_handler
int4: intx ack1 $4 interrupt_handler
int5: intx ack1 $5 interrupt_handler
int6: intx ack1 $6 interrupt_handler
int7: intx ack1 $7 interrupt_handler
int8: intx ack2 $8 interrupt_handler
int9: intx ack2 $9 interrupt_handler
int10: intx ack2 $10 interrupt_handler
int11: intx ack2 $11 interrupt_handler
int12: intx ack2 $12 mouse_handler
int13: intx ack2 $13 interrupt_handler
int14: intx ack2 $14 interrupt_handler
int15: intx ack2 $15 interrupt_handler
int128: intx ack0 $128 interrupt_handler
pit_handler:
call pit_interrupt_handler
push $0
push 8(%esp)
push 16(%esp)
call interrupt_handler
add $12,%esp
ret
kb_handler:
push %eax
mov $0x0,%eax
in $0x60,%al
pop %eax
push $0
push 8(%esp)
push 16(%esp)
call interrupt_handler
add $12,%esp
ret
mouse_handler:
push %eax
mov $0x0,%eax
in $0x60,%al
pop %eax
push $0
push 8(%esp)
push 16(%esp)
call interrupt_handler
add $12,%esp
ret
|