无操作系统环境下,加载外部程序后如何调用其otherMain()函数?
解决方案
要运行加载到内存的otherMain()函数,核心是准确定位到该函数在内存中的实际入口地址,再通过函数指针跳转执行。具体可通过以下几种方式实现:
1. 直接指定otherMain()的真实内存地址
编译外部程序时,用符号表工具(比如nm命令)查看目标文件,找到otherMain对应的内存地址(假设为0x0805)。然后修改主程序的函数指针定义:
void (*jumpToExec)(void) = (void (*)())0x0805; // 替换为otherMain的实际地址
调用loadExecutable()加载程序后,执行jumpToExec()就能直接运行otherMain()。
2. 将otherMain()设为外部程序的入口点
如果能控制外部程序的编译流程,直接把otherMain()指定为程序的入口函数:
- 编译时通过链接器参数设置,比如GCC用
-e otherMain选项,让链接器将otherMain()的地址作为程序起始地址。 - 此时外部程序加载到
0x0801后,该地址就是otherMain()的入口,原主程序的jumpToExec()可直接调用,无需修改地址。
3. 在外部程序中暴露入口地址(适配无法修改入口的场景)
在外部程序的固定内存位置(比如加载起始地址0x0801)存储otherMain()的函数指针:
- 修改外部程序代码:
// 在0x0801位置存放otherMain的指针 void (*const entryPoint)(void) __attribute__((section(".text.start"))) = otherMain; int otherMain() { printf("Hello, world!"); return EXIT_SUCCESS; }
- 主程序加载后,先读取
0x0801处的指针再跳转:
void loadExecutable(char* executable) { cbm_k_setnam(executable); cbm_k_setlfs(0, 8, 0); cbm_k_load(1, 0x0801); // 读取0x0801处的函数指针 void (*jumpToExec)(void) = *(void (**)())0x0801; jumpToExec(); }
内容的提问来源于stack exchange,提问作者Bunabyte
相关产品推荐
相关产品推荐

