首页 > 解决方案 > 将参数推送到调用堆栈的便携式方法 (C++)

问题描述

我正在编写一种小型脚本语言。

我正在寻找一种可移植的 C++ 方法将参数推送到调用堆栈上,以便我的函数可以正常读取它们。

这可能吗?它必须在 Visual Studio、XCode 和 Android Studio 中编译——最好使用嵌入在 C++ 中的 asm(不能选择使用外部汇编文件)

标签: c++parameterscallstack

解决方案


没有可移植的方法(我知道),因为“调用堆栈”不是可移植的东西。一台机器可能有不同的调用堆栈实现,例如 PIC18 设备具有单独的调用堆栈和变量堆栈,而 x86 共享使用相同的堆栈用于函数和变量以及返回值(用非常简单的话......)。
可能最好的方法是为您需要支持的每个架构和编译器创建一个单独的解决方案(宏或函数),然后使用预处理器条件结构来区分它们。使用 gcc 编译器时,您可以使用asm 关键字,而在 x86 架构上运行时,您可以使用push 指令将数据压入堆栈。
然后(半)便携式方法是提供一个 API,它的实现在架构和编译器之间发生变化,如下所示:

// for gcc and clang compiler for x86 architecture
#if defined(__GNUC__) && defined(__i386__)
#define PUSH_VALUE_ONTO_THE_CALL_STACK(val)  do{ \
/* this will break your code, dont use this */ \
int __v = (val); \
__asm__("push %0" : "r" (__v)); \
} while(0)
// for  Visual Studio compiler x86 architecture
#elif defined(_MSC_VER) && defined(__i386__)
#define PUSH_VALUE_ONTO_THE_CALL_STACK(val)  do{ \
/* this will break your code, dont use this */ \
__asm mov eax, val; \
__asm push eax; \
} while(0)
// add more
#elif defined(__PREDEFINED_MACRO_FOR_COMPILER) && defined(__PREDEFINED_MACRO_FOR_ARCHITECTURE)
#define PUSH_VALUE_ONTO_THE_CALL_STACK(val) /* implementation */
// when implementation is missing, issue a error
#else
#error Implementation PUSH_VALUE_ONTO_THE_CALL_STACK not found for Your architecture and compiler.
#endif

int main(void) {
      // identical usage/api between compilers and architectures
      PUSH_VALUE_ONTO_THE_CALL_STACK(5);
      return 0;
 }

希望这能让你走上正确的道路。
另外:XCode 只是 IDE 的名称,我认为 XCode 默认使用 clang。Android Studio可能使用 clang 或 gcc


推荐阅读