NASM 调用外部C++功能
NASM call for external C++ function
我正在尝试从NASM调用外部C++函数。当我在谷歌上搜索时,我没有找到任何相关的解决方案。
C++
void kernel_main()
{
char* vidmem = (char*)0xb8000;
/* And so on... */
}
纳斯姆
;Some calls before
section .text
;nothing special here
global start
extern kernel_main ;our problem
运行编译这两个文件后,我收到此错误:kernel.asm(.text+0xe): undefined reference to kernel_main'
这是怎么回事?谢谢。
到目前为止,还没有从汇编调用C++函数的标准化方法。这是由于称为名称重整的功能。C++编译器工具链不会发出名称完全写在代码中的符号。因此,您不知道表示用名称kernel_main
或kernelMain
编码的函数的符号的名称是什么。
为什么需要名称重整?
您可以在 C++ 中声明多个具有相同名称但位于不同父命名空间下的实体(类、函数、方法、命名空间等)。如果两个名称为本地名称的实体(例如命名空间SymbolDomain
中class SomeContainer
的本地名称SomeContainer
但全局名称SymbolDomain::SomeContainer
,至少在这个答案中讨论,好吧)具有相同的符号名称,则会导致符号冲突。
方法重载也会发生冲突,因此,对于类的方法,也会(以某种形式)发出每个参数的类型。为了解决这个问题,C++工具链将以某种方式破坏 ELF 二进制对象中的实际名称。
那么,我不能在程序集中使用C++损坏的名称吗?
是的,这是一种解决方案。您可以将readelf -s fileName
与对象文件一起使用,以便kernel_main
。您必须搜索与kernel_main
有一定相似性的符号。一旦你认为你得到了它,然后用echo _ZnSymbolName | c++filt
确认它应该输出kernel_main
.
您可以在程序集中使用此名称,而不是kernel_main
。
此解决方案的问题在于,如果由于某种原因更改了参数、返回值或其他任何内容(我们不知道什么会影响名称重整),则程序集代码可能会中断。因此,您必须小心这一点。另一方面,这不是一个好的做法,因为你要进入非标准的东西。
请注意,名称重整不是标准化的,并且因工具链而异。通过依赖它,您也坚持使用相同的编译器。
我不能做一些标准化的事情吗?
是的。您可以通过像这样声明函数extern "C"
来在C++中使用 C 函数
extern "C" void kernelMain(void);
这是您最好的解决方案,因为您的kernel_main
已经是一个没有父类和命名空间的 C 样式函数。请注意,C 函数是用 C++ 编写的,并且仍然使用C++功能(内部)。
其他解决方案包括使用宏间接寻址,其中 C 函数调用 C++ 函数(如果确实需要)。像这样的东西——
///
/// Simple class containing a method to illustrate the concept of
/// indirection.
///
class SomeContainer
{
public:
int execute(int y)
{
}
}
#define _SepArg_ , // Comma macro, to pass into args, comma not used directly
///
/// Indirection for methods having return values and arguments (other than
/// this). For methods returning void or having no arguments, make something
/// similar).
///
#define _Generate_Indirection_RetEArgs(ret, name, ThisType, thisArg, eargs)
extern "C" ret name ( ThisType thisArg, eargs )
{
return thisArg -> name ( eargs );
}
_Generate_Indirection_RetEArgs(int, execute, SomeContainer, x, int y);
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 询问在设计我的手臂模拟器功能表示格式1
- 功能原型的目的
- 这里在 Linux 中具有"CreatePipe"和"CreateProcessW"功能吗?