简体   繁体   English

假设在组合C和x86汇编时有一个调用约定

[英]Assuming a calling convention when combining C and x86 Assembly

I have some assembly routines that are called by and take arguments from C functions. 我有一些由C函数调用并从C函数中获取参数的汇编例程。 Right now, I'm assuming those arguments are passed on the stack in cdecl order. 现在,我假设这些参数以cdecl顺序在堆栈上传递。 Is that a fair assumption to make? 这是一个公平的假设吗?

Would a compiler (GCC) detect this and make sure the arguments are passed correctly, or should I manually go and declare them cdecl? 编译器(GCC)会检测到这一点并确保参数正确传递,还是我应该手动去声明它们cdecl? If so, will that attribute still hold if I specify a higher optimisation level? 如果是这样,如果我指定更高的优化级别,该属性是否仍然成立?

Calling conventions mean much more than just argument ordering. 调用约定不仅仅意味着参数排序。 There is a good pdf explaining all the details, written by Agner Fog: Calling conventions for different C++ compilers and operating systems . 有一个很好的pdf解释了所有细节,由Agner Fog编写: 调用不同C ++编译器和操作系统的约定

This is a matter of the ABI for the platform you're writing code for. 这是您编写代码的平台的ABI问题。 Almost all platforms follow the Unix System V ABI for C calling convention and other ABI issues, which includes both a general ABI (gABI) document detailing the common ABI characteristics across all CPU architectures, and a processor-specific ABI (psABI) document specific to the particular CPU architecture/family. 几乎所有平台都遵循Unix System V ABI for C调用约定和其他ABI问题,其中包括详细说明所有CPU体系结构中常见ABI特性的通用ABI(gABI)文档,以及特定于处理器的ABI(psABI)文档。特定的CPU架构/系列。 When it comes to x86, this matches what you refer to as "cdecl". 说到x86,这与你所说的“cdecl”匹配。 So from a practical standpoint, x86 assembly meant to be called from C should be written to assume "cdecl". 因此从实际的角度来看,意味着从C调用的x86程序集应该写成假设“cdecl”。 Basically the only exception to the universality of this calling convention is Windows API functions, which use their own nonstandard "stdcall" calling convention due to legacy Win16 dll thunk compatibility issues; 基本上,这个调用约定的普遍性的唯一例外是Windows API函数,由于传统的Win16 dll thunk兼容性问题,它们使用它们自己的非标准“stdcall”调用约定; nonetheless, the "default" calling convention on x86 Windows is still "cdecl". 尽管如此,x86 Windows上的“默认”调用约定仍然是“cdecl”。

A more important concern when writing asm to be called from C is whether symbol names should be prefixed with an underscore or not. 从C编写asm时,更重要的一个问题是符号名称是否应该以下划线为前缀。 This varies widely between platforms, with the general trend being that ELF-based platforms don't use the prefix, and most other platforms do... 这在平台之间差异很大,总的趋势是基于ELF的平台不使用前缀,而大多数其他平台都做...

The quick and dirty way to do it is create a dummy C function that matches the asm function you want to implement, do a few things in the dummy C function with the passed in parameters so you can tell them apart, compile then disassemble. 快速而肮脏的方法是创建一个与你想要实现的asm函数匹配的虚拟C函数,使用传入的参数在虚拟C函数中做一些事情,这样你就可以区分它们,编译然后反汇编。 Not foolproof but works often. 不是万无一失但经常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM