2015-02-11 34 views

回答

1

如果你做一些驱动程序/内核开发,你可以使用-nostdlib从臃肿的stdlib中删除你的模块。然而,为了在整个硬件上保持一致的行为,你还要删除GCC所有的内部攻击。

http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Link-Options.html

-nostdlib

不要使用标准系统启动文件或链接时库。没有启动文件,只有您指定的库将 传递给链接器,指定链接系统 库(如-static-libgcc或-shared-libgcc)的选项将被忽略。 编译器可能会生成对memcmp,memset,memcpy和memmove的调用。 这些条目通常由libc中的条目解析。当指定此 选项时,应通过其他一些机制提供这些条目 。

-nostdlib和-nodefaultlibs旁路的标准库之一是libgcc.a,它是GCC用来克服特定机器缺点的内部子例程库,或者某些语言​​的特殊需求 。 (有关libgcc.a的更多 讨论,请参阅与GCC输出接口,在大多数情况下,即使您想避开其他标准库,也需要libgcc.a。换句话说,当您在 中指定-nostdlib或-nodefaultlibs时,通常也应该指定-lgcc 。这可确保您没有未解决的对内部GCC库子例程的参考 。 (例如,`__main',用来 确保C++构造将被称为;参见collect2)

https://gcc.gnu.org/onlinedocs/gcc-4.6.1/gccint/Interface.html#Interface

3接口至GCC输出

GCC通常被配置为使用目标系统上正在使用的相同函数调用约定 。这是通过描述的 机器描述宏完成的(请参阅目标宏)。

但是,在某些目标机器上返回的结构和联合值的执行方式不同 。因此,返回这种类型的PCC 编译的函数不能从使用GCC编译的代码中调用,反之也不能使用 编译。这不会经常造成麻烦,因为很少的Unix库会返回结构或联合。

GCC代码返回长度为1,2,4或8个字节的结构和联合,其长度与用于int或双返回值的相同寄存器相同。 (GCC 通常也会在寄存器中分配这些类型的变量。) 其他大小的结构和联合通过将其存储到调用者传递的地址(通常在寄存器中)返回给 而返回。目标 挂钩TARGET_STRUCT_VALUE_RTX告诉GCC在何处传递此地址。

与此相反,在大多数目标机器PCC通过将数据复制到静态存储的区域返回结构和联合任何大小的 ,和 然后返回该存储的地址,好像它是一个指针 值。来电者必须将该存储区域的数据复制到需要值的地方 。这比GCC使用的方法 慢,并且不能重入。

在一些目标机器上,例如RISC机器和80386, 标准系统惯例是将要返回值的地址 传递给子例程。在这些机器上,当使用此方法时,GCC已配置为 以与标准编译器兼容。 它可能不兼容1,2,4或8个字节的结构。

GCC使用系统的标准惯例来传递参数。在 有些机器上,前几个参数传入寄存器;在 其他,所有都在堆栈上传递。在任何机器上使用 寄存器传递参数是可能的,这可能会导致显着的加速。但结果将是完整的 与遵循标准约定的代码不兼容。所以 只有当您切换到GCC作为系统的唯一 C编译器时,此更改才是实用的。一旦我们拥有完整的GNU系统,我们可以在某些机器上实现通过 的注册参数,以便我们可以用GCC编译库。

在某些机器(特别是SPARC)上,某些类型的参数 被“通过不可见参考”传递。这意味着值为 存储在内存中,并且内存位置的地址被传递给 子例程。

如果使用longjmp,请注意自动变量。 ISO C说 没有声明为volatile的自动变量在longjmp后面有未定义的 值。这就是GCC所做的所有承诺,因为 很难正确恢复寄存器变量,并且GCC的一个特性是可以将变量存入寄存器,而不需要你的要求。

相关问题