【发布时间】:2010-09-17 13:48:38
【问题描述】:
我正在使用带有一些内联汇编代码的 Borland Turbo C++,所以大概是 Turbo Assembler (TASM) 风格的汇编代码。我希望做到以下几点:
void foo::bar( void )
{
__asm
{
mov eax, SomeLabel
// ...
}
// ...
SomeLabel:
// ...
}
所以 SomeLabel 的地址被放入 EAX 中。这不起作用,编译器抱怨:未定义的符号'SomeLabel'。
在 Microsoft Assembler (MASM) 中,美元符号 ($) 用作当前位置计数器,这对我的目的很有用。但这似乎在 Borlands Assember 中不起作用(表达式语法错误)。
更新:更具体一点,我需要编译器在编译/链接期间而不是在运行时生成它作为常量移动到 eax 中的地址,因此它会像“mov eax, 0x00401234”一样编译。
谁能建议如何让它工作?
更新:为了回答 Pax 的问题(请参阅评论),如果 Windows 加载程序在运行时更改了基地址,则 DLL/EXE PE 映像仍将由 Windows 加载程序重新定位,并且标签地址将被修补为加载程序在运行时使用基于重定位的地址,因此对标签地址使用编译/链接时间值不是问题。
非常感谢。
【问题讨论】:
-
如果您在 asm 块中定义 SomeLabel 是否有效?
-
对于gcc,获取labels地址是“&&label”,你试过吗?也许它也适用于 borland?
-
您打算如何在编译时获取值?加载器可能会更改(在加载时,链接后很长时间)加载此代码的地址,使您的编译/链接值无用。
-
也许你需要重申一下这个问题:一旦 eax 被加载,你到底要做什么。
-
paxdiablo:Windows PE 加载器将重新定位一个 exe 并处理 PE 文件的 .reloc 部分,使用新加载的基地址更新任何固定地址,因此 EAX 将始终正确。此外,加载 EAX 后我将如何处理它也不重要,问题是如何将 EAX 设置为 SomeLabel 的地址(这在 MSVC 中很容易实现,而不是 C++ Builder)。
标签: c++ assembly x86 turbo-c++