如何让我用 SysV 调用约定编译的 C 程序在 MinGW 下运行

问题描述

我的平台是 x86_64 + Windows 10 + Cygwin。我的编译器是 x86_64-w64-mingw32-gcc

出于某种原因,我不得不使用 -mabi=sysv 选项编译我的程序,如果可能的话,我想避免使用认的 -mabi=ms 选项。

程序编译成功。但是当它调用printf 这样的库函数时,它错误。原因是库函数驻留在 msvcrt.dll 中,它可能是使用除 -mabi=sysv 之外的调用约定预先构建的。

那么,有没有办法在 Cygwin 中安装使用 -mabi=sysv 编译的库?

解决方法

根据您对手写汇编的评论,您似乎正在亲身体验汇编实际上并不那么便携,以及为什么历史上需要更便携的高级语言,如 C。

您崩溃的原因可能是由于两个 ABI 之间的寄存器使用不同。调用函数时,ABI 定义了与每个参数关联的寄存器。因此,当您使用一个 ABI 调用库函数时,该库之前是为不同的 ABI 编译的,该库代码将查看其指定的寄存器并可能访问内存,从而导致未定义的行为。

我认为虽然获得库可以解决您的问题,但我认为存在一种误解。想一想您得到了想要的东西,即针对 System V ABI 编译的 windows C 运行时库。现在,当您的程序调用 printf(...) 时,您至少将在正确的寄存器中拥有您的参数。但是文本必须打印到控制台,因此必须要求内核介入并使其发生。为了进行该系统调用,将使用 Windows API 库,并且将发生另一个 ABI 不匹配。所以你可以看到这个困境是如何上升到顶部的。您基本上需要一个针对 System V ABI 或某种其他形式的兼容层(例如 WINE 的工作原理)编译的完整 Windows 操作系统。

您可能有两种选择。重写程序集以匹配本机 Windows ABI,或考虑使用提供完整(但虚拟化)Linux 环境的 WSL。