我试图参加一些集会。我的理解是,系统调用是通过syscall
指令生成的中断进行的。
但是使用clang -S
在计算机上编译一个简单程序后:
int main() {
write(0, "HI", 2);
return 0;
}
生成的相关程序集是:
movl $0, -4(%rbp)
leaq L_.str(%rip), %rsi
movl $2, %edx
movb $0, %al
callq _write
为什么?
是否有办法查看在OS X上正在执行的实际sys调用?
因为您正在从C标准库中调用函数。该功能可能会也可能不会包装系统调用,可能会使用意外的系统调用(例如比原始系统调用更现代的系统调用),并且通常必须执行各种设置和拆卸操作以适应C和系统调用调用约定。
包装器通常很薄,但是它仍然是包装器(例如,在linux上,系统调用通常在失败的情况下返回成功或-errno
,libc然后必须检查是否失败,将errno存放在相应的threadlocal和返回标准或POSIX定义的“适当”值)。
您正在看到这是因为所有系统调用都由Apple包装,并在libsystem_kernel.dylib
中定义了外观层。苹果之所以这样做,是因为系统调用号码不是公共接口,并且在MacOS版本之间可能会发生变化。启动程序时,可以使用以下命令验证lldb中实际的系统调用:
lldb ./a.out
b write
run
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00007fff63e0f040 libsystem_kernel.dylib`write
libsystem_kernel.dylib`write:
-> 0x7fff63e0f040 <+0>: mov eax, 0x2000004
0x7fff63e0f045 <+5>: mov r10, rcx
0x7fff63e0f048 <+8>: syscall
0x7fff63e0f04a <+10>: jae 0x7fff63e0f054 ; <+20>
Target 0: (a.out) stopped.
(lldb)