第38部分-Linux x86 64位汇编 系统调用和C库
C库提供了丰富的函数,可以在汇编语言中利用他们。
C库函数包含在libc库中,必须连接到汇编语言程序中。C库包含在man页的第3部分。系统调用包含在man页的第2部分。
跟踪C函数示例
.section .data
output:
.asciz "This is a test\n"
temp:
.int 0
.section .text
.globl _start
_start:
movq $10, %rcx
loop1:
movq %rcx, temp
movq $output,%rdi
call printf
movq $5, %rdi
call sleep
pop %rcx
movq temp,%rcx
loop loop1
movq $0,%rdi
call exit
as -g -o cfunctest.o cfunctest.s
ld -o cfunctest cfunctest.o -lc -I /lib64/ld-linux-x86-64.so.2
运行cfunctest后使用strace进行跟踪
strace: Process 88728 attached
restart_syscall(<... resuming interrupted nanosleep ...>) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039be70) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039be78) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039be80) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039be88) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039be90) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039be98) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffe2039bea0) = 0
write(1, "This is a test\n", 15) = 15
nanosleep({tv_sec=5, tv_nsec=0},
我们发现C库和系统调用基本一致。
另外,我们在执行的时候,使用strace -c ./cfunctest
# strace -c ./cfunctest
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 1 read
0.00 0.000000 0 10 write
0.00 0.000000 0 2 close
0.00 0.000000 0 3 fstat
0.00 0.000000 0 5 mmap
0.00 0.000000 0 4 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 3 brk
0.00 0.000000 0 3 3 access
0.00 0.000000 0 10 nanosleep
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 2 openat
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 46 3 total
# strace -c ./nanotest
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
This is a test
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 10 write
0.00 0.000000 0 10 nanosleep
0.00 0.000000 0 1 execve
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 21 total
使用C库使用了46次系统调用,而nanotest只使用了21次系统调用。
C库和系统调用小结
从而我们可以得出结论,系统调用的好处是:
- 代码长度短,不需要把外部库连接到程序中
- 速度快,不需要外部库连接到程序中。
- 连接后可执行文件独立于外部代码,只依赖内核系统调用。
使用C库的好处是:
- 包含函数多,而汇编去实现比较费力。
- C库在操作系统之间可移植。
- C库函数在程序间利用共享,减少内存需求。