通常,系统提供一个位于正常程序和操作系统之间的库或API。在类Unix系统中,该API通常是C库(libc)实现的一部分,例如作为glibc,为系统调用提供包装函数。 现在C程序可以调用这些库函数,因为这些库函数是用C语言编写的,并进行系统调用。 Cobol或任何其他基于编译器的语言如何在Linux上进行系统调用?这些语言不能调用系统提供的API。在Linux机器上调用系统调用
回答
编译语言被翻译(编译)成机器语言。操作系统在执行过程中读取机器语言并进行适当的系统调用。
所以,我不会说它是C或任何编译语言,这使得系统调用。操作系统根据编译器生成的机器语言执行系统调用。
这不是那么简单 - 你必须了解ABI才能知道*如何进行这些调用。 – 2014-10-17 12:40:11
编译器必须理解ABI才能做到这一点? – saurav1405 2014-10-17 12:45:34
@ saurav1405是的。编写编译器/解释器和/或运行时库的人员必须了解运行编译器的平台的系统调用ABI以及他们希望语言在特定平台上调用哪些系统调用。 – nos 2014-10-17 13:50:51
一个例子可能有所帮助:如果我编译一个简单的Fortran程序像这样与gfortran:
PROGRAM HELLO
WRITE(*,*) "HELLO WORLD"
END
我得到的代码看起来像这样(在X86-64):
000000000040079d <MAIN__>:
40079d: 55 push %rbp
40079e: 48 89 e5 mov %rsp,%rbp
4007a1: 48 81 ec e0 01 00 00 sub $0x1e0,%rsp
4007a8: 48 c7 85 28 fe ff ff movq $0x4008e0,-0x1d8(%rbp)
4007af: e0 08 40 00
4007b3: c7 85 30 fe ff ff 03 movl $0x3,-0x1d0(%rbp)
4007ba: 00 00 00
4007bd: c7 85 20 fe ff ff 80 movl $0x80,-0x1e0(%rbp)
4007c4: 00 00 00
4007c7: c7 85 24 fe ff ff 06 movl $0x6,-0x1dc(%rbp)
4007ce: 00 00 00
4007d1: 48 8d 85 20 fe ff ff lea -0x1e0(%rbp),%rax
4007d8: 48 89 c7 mov %rax,%rdi
4007db: e8 c0 fe ff ff callq 4006a0 <[email protected]>
4007e0: 48 8d 85 20 fe ff ff lea -0x1e0(%rbp),%rax
4007e7: ba 0b 00 00 00 mov $0xb,%edx
4007ec: be e7 08 40 00 mov $0x4008e7,%esi
4007f1: 48 89 c7 mov %rax,%rdi
4007f4: e8 57 fe ff ff callq 400650 <[email protected]>
4007f9: 48 8d 85 20 fe ff ff lea -0x1e0(%rbp),%rax
400800: 48 89 c7 mov %rax,%rdi
400803: e8 78 fe ff ff callq 400680 <[email protected]>
400808: c9 leaveq
400809: c3 retq
在有您可以看到三次调用gfortran库函数(例如gfortran_transfer_character_write
)。它看起来像gfortran插入这些来实现WRITE
声明。库函数为implemented in C,最终将通过C库包装器调用底层系统调用。
当编译器构造对这些函数的调用时,它必须遵循C调用约定并对调用语言的数据类型执行任何转换。除此之外,这里没有魔法。一旦你在运行时库中,你可以调用其他C库(如libc)。
@ benj非常感谢。我理解一种语言如何使用libc来调用系统调用,但是如何在不使用libc的情况下直接调用系统调用?我需要为此编写汇编代码吗? – saurav1405 2014-10-17 14:08:45
http://stackoverflow.com/questions/13219501/accessing-a-system-call-directly-from-user-program可能有助于那个 – benj 2014-10-20 13:50:46
- 1. 在Linux上seteuid系统调用?
- 2. x86 linux系统调用调用约定?
- 3. Linux系统调用getifaddr C++
- 4. 开放系统调用 - Linux
- 5. linux系统调用getpeername C++
- 6. linux系统中使用的for_each_zone在新系统调用中调用
- 7. 在Linux中创建系统调用
- 8. 在Linux的NFS挂载系统调用
- 9. 在Linux系统()调用的问题
- 10. 如何在Python中调用linux系统调用PROCESS_VM_READV?
- 11. 如何在golang中调用Linux/UNIX的系统调用
- 12. 消息队列。 msgsend msgrcv。系统V在C系统调用(Linux)
- 13. 如何禁止系统调用GNU/Linux
- 14. Linux glibc系统调用包装位置
- 15. 冗余的Linux内核系统调用
- 16. Android Linux系统调用列表
- 17. Linux:通过ptrace()执行系统调用()
- 18. Linux系统调用的Java断点
- 19. 编写一个系统调用linux
- 20. Linux系统调用返回值
- 21. x86_64汇编Linux系统调用混淆
- 22. 我怎么拦截linux系统调用?
- 23. Linux系统调用流程序列号
- 24. Armv8的Linux系统调用约定
- 25. 当我寻找添加系统调用时,我添加系统调用linux-2.6.31
- 26. 从C++应用程序代码调用Linux系统调用?
- 27. 系统(“”)调用
- 28. 在64位系统上添加新的系统调用到Linux Kernel 3.13
- 29. 在Linux中调度中断和系统调用
- 30. 系统调用在Linux上如何实际发生?
他们很高兴刚刚使用libc。其他不太聪明的运行时可能会通过他们自己的内核版本支持地狱。 – user3125367 2014-10-17 12:32:08
“这些语言不能调用系统提供的API。”为什么不? – glglgl 2014-10-17 12:36:38
他们如何调用libc函数? – saurav1405 2014-10-17 12:37:33