-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsyscall.c
49 lines (42 loc) · 1.86 KB
/
syscall.c
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
#define pop_all_but_ax\
" pop %bx ;"\
" pop %bx ;"\
" pop %cx ;"\
" pop %dx ;"\
" pop %si ;"\
" pop %di ;"\
" pop %bp ;"
/* Write a string on the standard output.
Arguments: bx pointer to the string.
*/
void __attribute__((naked)) sys_write(void){
__asm__(
" pusha ;" /* Push all registers */
" mov $0x0e, %ah ;" /* Video BIOS service: teletype mode */
" mov $0x0, %si ;"
"loop2: ;"
" mov (%bx, %si), %al ;" /* Read character at bx+si */
" cmp $0x0, %al ;" /* Repeat until end of string (0x0) */
" je end2 ;"
" int $0x10 ;" /* Call video BIOS service */
" add $0x1, %si ;" /* Advace to the next character */
" jmp loop2 ;" /* Repeat the procedure */
"end2: ;"
" mov %si, %ax ;" /*Return string length in %ax */
pop_all_but_ax
" ret ;"
);
}
/* Array pointing to all syscall functions. */
void (*syscall_table[])() = {
sys_write /* 0 : SYS_WRITE. */
};
/* Syscall handler.
Attribute regparm(2) modifies the calling convention such that
the arguments are passed through registers ax, dx and cx, respectively.
Syscall functions should look for their arguments in those registers.
*/
void __attribute__((naked)) syscall_handler(int number, int arg1, int arg2, int arg3){
syscall_table[number]();
__asm__("iret");
}