如何在没有标准 C 库的情况下使用编译器内置函数

use*_*913 2 c c++ optimization gcc built-in

我知道有些函数sin cos min max memcpy可能不被视为普通函数,而是可能被内置函数替换(当替换是(一个)实际的处理器指令时,这可能比仅仅内联函数调用更优化,例如为带浮点单元的 x86 编译时直接调用FSIN标准sin函数的指令)。

我想使用内置函数的强大功能(在 C/C++ 中,主要是在 mingw/gcc 中可能是其他编译器),但我不想链接到标准 C 库 libc)。

  • 是否可以在不链接到 libc 的情况下使用内置函数?

  • 它们是否需要将这些符号优化为内置函数所需的任何命令行标志?

    (与之前有关,但改写了)

  • 它们会被名称自动识别,还是需要编译器标志才能使用内置函数?

mct*_*ylr 5

@randomusername 已经解释了__builtin_许多常见标准 C 库函数的前缀用法。我建议使用#define来进行更改,同时保持您的代码干净。

#include <math.h>

#define  cos   __builtin_cos
#define  sin   __builtin_sin
#define  printf __builtin_printf

...
   printf("Distance is %f\n", cos(M_PI/4.0) * 7);
...
Run Code Online (Sandbox Code Playgroud)

没有标准 C 库

现在不使用标准 C 库,这意味着不链接到它,或者包括典型的启动和退出代码存根,好吧,使用 GCC 可以使用-nostdlibwhich 等价于-nostartfiles-nodefaultlibs

问题是您必须替换您通常使用的所有库函数,包括任何基于内核的函数的系统调用(或它们的包装器/来自 glibc 的宏)。

我不知道的便携式或可靠的方法是在处理器,甚至作品必然不同家庭(SYSENTER与系统调用(指令)对int 0x80各种32位和64位x86处理器)。有与问题ELF辅助向量Elf32_auxv_t)和VDSO虚拟ELF动态共享对象),可能是可能的地址,并创建一个便携的解决方案,我不知道。

入口点

我相信所有 GCC 环境都使用相同的默认入口点,即 label/function _start。这通常包含在“启动文件”中,然后调用main. 所以你需要用你自己的最小存根(可以是 C 语言)替换它。

程序终止

我不知道如何以_exit(rc)可移植的方式替换或正确终止程序所需的类似功能。例如,在 Linux 环境中,它需要对内核函数SYS_exit(又名__NR_exitsys_exit)进行系统调用

void _start(void) {
    int rc;
    /* Get command line arguments if necessary */
    rc = main(0, NULL);
    your_exit_replacement(rc);
}
Run Code Online (Sandbox Code Playgroud)

备择方案

通常用户进程,即应用程序,与操作系统内核或驱动程序相反,接受链接启动文件的开销和启用动态链接到 Startard C 库的必要开销,因为内存被认为便宜且易于获得,对于任何实际的(实际上做了一些事情)应用程序节省内存是不值得的。在嵌入式域中,仅仅假设有足够的内存可用是不可接受的,替代方案是使用最小的 libc 替换。对于 Linux,有几个可用的(例如 musl、uClibc、dietlibc),我不知道是否有一个可用于 mingw 或 Windows 兼容的开源替代品(ReactOS 和 Wine)。

更远

有关更多信息,从 Linux 平台的角度来看,有一个很好的介绍“Hello from a libc-free world!” 第 1 部分第 2 部分由 Jessica McKellar 在甲骨文的博客撰写。还有一些相关的问题,以及一些(在某些情况下部分)在stackoverflow 上关于在各种情况下使用 -nostdlib 的答案。

从这里走向何方取决于您的目标:教育、嵌入式、微型程序(Linux ELF 可执行文件)或 Windows PE 可执行文件竞赛。

微软Windows

有各种关于处理 .COM 和 .EXE 可执行文件的 Microsoft Windows 环境和 Windows PE 的文章,但通常使用 Microsoft 的 Visual Studio 环境或程序集。在“经典”是马特·皮特里克的发动机罩下的列“减少EXE和DLL尺寸与LIBCTINY.LIB”(MSDN杂志的2001年1月号)和“从应用程序中使用我们的32位吸脂工具删除脂肪堆积”从1996年10月微软系统杂志。另一篇文章,但我没有读过自己,似乎包含解释的是“减少可执行文件大小”