8 %include "sconst.inc" 9 10 _NR_get_ticks equ 0 ; 要跟 global.c 中 sys_call_table 的定义相对应! 11 INT_VECTOR_SYS_CALL equ 0x90 12 13 14 ; 导出符号 15 global get_ticks 16 17 18 bits 32 19 [section .text] 20 21 ; ==================================================================================== 22 ; get_ticks 23 ; ==================================================================================== 24 get_ticks: 25 mov eax, _NR_get_ticks;用eax传递系统调用参数 26 int INT_VECTOR_SYS_CALL 27 ret
61 PUBLIC void init_prot() 62 { 63 init_8259A(); 64 65 // 全部初始化成中断门(没有陷阱门) ...... 98 init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate, sys_call, PRIVILEGE_USER); }
因为我们使用了eax来传递系统调用的参数,但是eax又被用于保存进程上下文中的运算,所以我们修改save函数,其中的eax换成esi:
save: ... 325 mov esi, esp ; esi = 进程表起始地址 326 327 inc dword [k_reenter] ; k_reenter++; 328 cmp dword [k_reenter], 0 ; if(k_reenter ==0) 329 jne .1 ; { 330 mov esp, StackTop ; mov esp, StackTop <-- 切换到内核栈 331 push restart ; push restart 332 jmp [esi + RETADR - P_STACKBASE] ; return; 333 .1: ; } else { 已经在内核栈,不需要再切换 334 push restart_reenter ; push restart_reenter 335 jmp [esi + RETADR - P_STACKBASE] ; return; 336 ; } ... ret
342 sys_call: 343 call save 344 345 sti 346 347 call [sys_call_table + eax * 4] 348 mov [esi + EAXREG - P_STACKBASE], eax 349 350 cli 351 352 ret
28 PUBLIC t_sys_call sys_call_table[NR_SYS_CALL] = {sys_get_ticks}; 23 typedef void* t_sys_call;注意,这是一个指针,不是一个函数指针
45 PUBLIC int sys_get_ticks() 46 { disp_str("+"); 47 return ticks; 48 }
47 /* proc.c */ 48 PUBLIC int sys_get_ticks(); /* t_sys_call */ 49 50 /* syscall.asm */ 51 PUBLIC void sys_call(); /* t_pf_int_handler */ 52 PUBLIC int get_ticks();我们来理清调用关系:get_tricks >>sys_call(eax=!!) >> sys_get_tricks
70 void TestA() 71 { 72 while(1){ get_tricks(); 73 disp_str("A"); 74 disp_int(i++); 75 disp_str("."); 76 delay(1); 77 } 78 }然后编译运行即可。
59 /* 初始化 8253 PIT */ 60 out_byte(TIMER_MODE, RATE_GENERATOR); 61 out_byte(TIMER0, (t_8) (TIMER_FREQ/HZ) ); 62 out_byte(TIMER0, (t_8) ((TIMER_FREQ/HZ) >> 8)); 63 /* 初始化 8253 PIT 完毕 */
40 PUBLIC void milli_delay(int milli_sec) 41 { 42 int t = get_ticks(); 43 44 while(((get_ticks() - t) * 1000 / HZ) < milli_sec) {} 45 }
76 void TestA() 77 { 78 while(1){ 79 disp_str("A"); 80 disp_int(get_ticks()); 81 disp_str("."); 82 milli_delay(1000); 83 } 84 }
《自己动手写操作系统》 第六章 系统调用的实现,布布扣,bubuko.com
原文:http://blog.csdn.net/trochiluses/article/details/21988205