2014-10-17 58 views
1

通常,系统提供一个位于正常程序和操作系统之间的库或API。在类Unix系统中,该API通常是C库(libc)实现的一部分,例如作为glibc,为系统调用提供包装函数。 现在C程序可以调用这些库函数,因为这些库函数是用C语言编写的,并进行系统调用。 Cobol或任何其他基于编译器的语言如何在Linux上进行系统调用?这些语言不能调用系统提供的API。在Linux机器上调用系统调用

+2

他们很高兴刚刚使用libc。其他不太聪明的运行时可能会通过他们自己的内核版本支持地狱。 – user3125367 2014-10-17 12:32:08

+1

“这些语言不能调用系统提供的API。”为什么不? – glglgl 2014-10-17 12:36:38

+1

他们如何调用libc函数? – saurav1405 2014-10-17 12:37:33

回答

0

编译语言被翻译(编译)成机器语言。操作系统在执行过程中读取机器语言并进行适当的系统调用。

所以,我不会说它是C或任何编译语言,这使得系统调用。操作系统根据编译器生成的机器语言执行系统调用。

+0

这不是那么简单 - 你必须了解ABI才能知道*如何进行这些调用。 – 2014-10-17 12:40:11

+0

编译器必须理解ABI才能做到这一点? – saurav1405 2014-10-17 12:45:34

+1

@ saurav1405是的。编写编译器/解释器和/或运行时库的人员必须了解运行编译器的平台的系统调用ABI以及他们希望语言在特定平台上调用哪些系统调用。 – nos 2014-10-17 13:50:51

0

一个例子可能有所帮助:如果我编译一个简单的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)。

+0

@ benj非常感谢。我理解一种语言如何使用libc来调用系统调用,但是如何在不使用libc的情况下直接调用系统调用?我需要为此编写汇编代码吗? – saurav1405 2014-10-17 14:08:45

+0

http://stackoverflow.com/questions/13219501/accessing-a-system-call-directly-from-user-program可能有助于那个 – benj 2014-10-20 13:50:46