Visual-C ++内联汇编程序两个偏移量的差异

我正在将一大堆代码从MASM移植到C内联汇编程序(x86,Windows,MS VC)。欺骗不是真正的代码,只是欺骗提出一个想法。 假设我将一些数据定义为静态数组,甚至是两个标签之间的代码块,我需要获得它的大小。

label1: bla bla bla label2: .... mov eax, (offset label2 - offset label1) 

这样的代码在MASM中像魅力一样工作,但在CI中得到以下错误消息:“错误C2425:’ – ‘:’第二个操作数’中的非常量表达式”我可以编译:

  mov eax, offset label1 mov eax, offset label2 

我希望编译器在编译时评估(偏移label1 – 偏移label2),但看起来我错了。 我也不能添加偏移量(为什么?这些只是在编译期间添加的两个整数……?)当然,我可以获得mov eax,offset label2 mov edx,offset label1 sub eax,edx编译,但这是一个额外的代码只是为了计算常数。 有人可以解释一下,我的代码有什么问题吗?

这可能是搬迁造成的吗? 如何推动它?

期待一个答案,谢谢。

是的,它可能是由于重新安置的威胁造成的,也可能是由于可变长度指令处理相对跳跃的威胁造成的。 很可能是因为一些小麻烦,汇编程序编写者采取了简单的方法并实现了1遍或2遍编译器,尽快做出最终决定。 因此不支持一些方便的表达。

正如评论中已经建议的那样,汇编程序仍然可能支持mov + sub组合。

在获得所有标签的固定地址之前,真正的汇编程序可能会在几次传递中运行代码。 例如,某些跳跃有短的和长的forms,具体取决于你想跳多远。 如果标签之间有这样的跳跃,则距离取决于跳转的位置。

C编译器可能会将其中一些内容留给链接器/加载器,而不是在编译时修复这些值。

您可以将addres计算代码简化为两条指令

 mov EAX, offset Label2 sub EAX, offset Label1 

我认为这不会完全破坏代码的性能。