Tag: abi

什么ABI,如果有的话,限制 intmax_t的大小?

从1999版本开始,ISO C标准定义了一个标准头文件 ,它定义了typedef intmax_t和uintmax_t 。 它们分别指定“能够表示任何(有符号|无符号)整数类型的任何值的一个(有符号|无符号)整数类型”。 例如,如果典型地,最宽的有符号和无符号整数类型是long long int和unsigned long long int ,两者通常都是64位,那么intmax_t和uintmax_t可能在定义如下: typedef long long int intmax_t; typedef unsigned long long int uintmax_t; 有一组有限的预定义有符号和无符号整数类型,范围从signed , unsigned和plain char到signed和unsigned long long int 。 C99和C11还允许实现定义扩展的整数类型 ,这些类型不同于任何标准类型,并且具有实现定义的关键字的名称。 gcc和clang在某些但不是所有目标上都支持__int128和unsigned __int128类型。 这些行为类似于128位整数类型,但它们不被视为扩展整数类型 ,并且两个编译器的文档都声明它们不支持任何扩展整数类型。 由于这些不是整数类型,因为标准定义了术语,因此intmax_t和uintmax_t适用于64位类型,而不是128位类型。 这些都不违反C标准(实现不需要具有任何扩展的整数类型,并且只要它们不破坏任何严格符合的程序,它们就被允许具有任意扩展)。 但在我看来,将__int128和unsigned __int128视为扩展整数类型,并将intmax_t和uintmax_t视为128位类型是intmax_t uintmax_t 。 不这样做的基本原理是改变intmax_t和uintmax_t的大小将是“ABI不兼容的变化”。 Clang C ++状态页面在脚注(5)中说: 对于没有提供任何扩展整数类型的Clang等实现,不需要进行编译器更改。 __int128不被视为扩展整数类型,因为更改intmax_t将是ABI不兼容的更改。 (是的,这主要讨论C ++,但规则与C相同) 在gcc错误报告中 ,声称: sizeof(intmax_t)由各种LP64 […]

C LLI与LLVM

我有一个用LLVM编写的编译器,我正在寻求提高我的ABI合规性。 例如,我发现很难在Windows x86或Linux上找到C ABI的规范文档。 我发现的那些用RAX / EAX /等​​解释它,而不是我可以使用的IR术语。 到目前为止,我认为我认为LLVM无形地处理聚合 – 也就是说,它将每个成员视为一个独特的参数。 例如,在Windows x64上,如果我想处理像文档所说的聚合,我需要强制转换为该大小的单个整数,如8,16,32或64位。 否则,通过指针传递。 对于Windows x86,似乎__cdecl和__stdcall不需要我的任何操作,因为所有参数都在堆栈上传递。 __fastcall说前两个32位或更小的参数是寄存器传递的,所以我需要强制大小或更小的聚合。 __thiscall在寄存器中传递它,其余的在堆栈中,所以看起来我不需要在这里执行任何调整。 对于__vectorcall,通过整数强制传递不超过sizeof(void *)的聚合。 对于其他聚合,如果它们是HVA,则按值传递; else在x86上传递值或在x64上传递指针。 这似乎很简单(相对而言),但是sext的LLVM文档明确指出“这表明代码生成器应该将参数或返回值符号扩展到目标的ABI所需的范围(通常为32位) )由调用者(对于参数)或被调用者(对于返回值)。“ x86调用约定的Microsoft页面没有提及任何扩展任何宽度的内容。 我观察到Clang生成的LLVM IR在Windows上生成了byval属性。 我从上面收集到的理解从未要求使用byval 。 如何将各种平台C ABI降低到LLVM IR?

如何在汇编语言中使用c库函数fgets?

如标题所述,如何在汇编语言中使用c库函数fgets? 实际上,我想知道如何获取stdin的文件指针。 感谢您的回复。

库ABI Visual Studio版本之间的兼容性

我有两个场景。 假设我有3个导出C ++符号的共享库,每个库都使用VS7.1,VS8和VS9构建。 我在VS9中编译了所有3个。 出于某种原因,这是有效的。 我不需要在VS9中为VS9链接器重新编译前两个库,以便成功找到符号并链接它们。 现在,如果我有一个只使用C语法(extern“C”)导出符号的库,这是一样的吗? 我听说有人说ABI for C是标准化的,所以在某种程度上保证你可以在所有版本的Visual Studio中使用Visual Studio 8中编译的C库。 基本上,所有这些事情的结合令人困惑。 我不确定在不同版本的Visual Studio之间链接C ++和基于C的共享库(使用相应的导入库)之间有什么保证。 我想听听关于任何其他版本的Visual Studio上C 和 C ++导入或静态库的向前/向后兼容性的一致意见。 这对我来说是因为我使用的闭源库是在Visual Studio .NET 2003(VS7.1)中编译的。 我的团队认为这将我们锁定到VS 7.1编译器,但是我已经在VS8和VS9中测试了这些库,甚至是VS2010,它们链接得很好。 但是,我不确定这个内在的危险。 请注意,所讨论的库具有C变体和C ++变体。 基本上,C变量是标准C导出,而C ++库是C库和导出类的抽象。

从程序集调用C / C ++函数(OSX Mavericks x64)

这是一个奇怪的问题,我似乎无法找到答案。 这个: #include using namespace std; void show_number(int number) { cout << number << endl; // Shows '10' as expected } int main() { cout << endl; // Remove this and it fails __asm { mov rdi, 10 call show_number } } 实际上工作正常,除非你删除初始cout << endl ( main第一行)。 当你删除它时, show_number的cout似乎由于某种原因导致段错误。 是什么导致这个? (OSX Mavericks x64,但我认为应该在linux中工作)

如何在x86-64上优化C和C ++中的函数返回值?

x86-64 ABI指定两个返回寄存器: rax和rdx ,大小均为64位(8字节)。 假设x86-64是唯一的目标平台,这两个function中的哪一个: uint64_t f(uint64_t * const secondReturnValue) { /* Calculate a and b. */ *secondReturnValue = b; return a; } std::pair g() { /* Calculate a and b, same as in f() above. */ return { a, b }; } 考虑到针对x86-64的C / C ++编译器的当前状态,会产生更好的性能吗? 使用一个版本或其他版本在性能方面是否有任何陷阱? 编译器(GCC,Clang)总是能够优化在rax和rdx返回的std::pair吗? 更新:通常,如果编译器优化了std::pair方法(使用GCC 5.3.0和Clang 3.8.0的二进制输出示例),则返回一对更快。 如果没有内联f() ,编译器必须生成代码以将值写入内存,例如: movq […]

C有标准的ABI吗?

从其他地方的讨论: C ++没有标准的ABI 但C也不是吗? 在任何给定的平台上它几乎都可以。 如果没有语言交流,那么作为语言间交流的通用语言就没有用。 你对此有何看法?

如果他们定义了标准的ABI,C / C ++会“丢失”什么?

标题说明了一切。 我特别谈论C / C ++,因为他们都认为这是“实施问题”。 我认为,定义标准接口可以轻松构建模块系统,以及许多其他好东西。 如果他们定义了标准的ABI,C / C ++会“丢失”什么?