中断之后,进入_system_call,(定义在linux-0.11/kernel/system_call.s)
-
_system_call:
-
-
cmpl $nr_system_calls-1,%eax
-
-
ja bad_sys_call
-
-
push %ds
-
-
push %es
-
-
push %fs
-
-
pushl %edx
-
-
pushl %ecx # push %ebx,%ecx,%edx as parameters
-
-
pushl %ebx # to the system call
-
-
movl $0x10,%edx # set up ds,es to kernel space
-
-
mov %dx,%ds
-
-
mov %dx,%es
-
-
movl $0x17,%edx # fs points to local data space
-
-
mov %dx,%fs
-
-
call _sys_call_table(,%eax,4)
-
-
pushl %eax
-
-
movl _current,%eax
-
-
cmpl $0,state(%eax) # state
-
-
jne reschedule
-
-
cmpl $0,counter(%eax) # counter
-
-
je reschedule
_system_call 根据系统调用号,结合_sys_call_table计算所要调用的系统调用的地址,然后就call (call _sys_call_table(,%eax,4))(sys_call_table[]定义在linux-0.11/include/linux/sys.h)
-
fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
-
-
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
-
-
sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
-
-
sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
-
-
sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
-
-
sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
-
-
sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
-
-
sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
-
-
sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
-
-
sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
-
-
sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
-
-
sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
-
-
sys_setreuid,sys_setregid }
call _sys_call_table(,%eax,4) 调用的说
sys_call_table.,两个变量名字差一个下划线,但的的确确,前面那个call指令访问的说后面那个数组。
原因分析:
编译器在编译C语言的时候,会在每个函数的名称前面添加一个下划线,目的是防止函数名称和库函数重名。 C专家编程 5.4 章节interpositioning 讲解了原理。至于添加下划线的方法,是unix C 的规则。
所以在汇编语言调用C语言的时候,访问C语言符号的时候,要添加上下划线。 直接访问符号可以省一个符号 ,不用倒了,至于怎么倒。。。。
阅读(1468) | 评论(0) | 转发(0) |