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

时间:2012-11-16 16:39:55

标签: c windows x86 inline-assembly

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

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

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

    mov eax, offset label1
    mov eax, offset label2

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

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

期待一个答案, 谢谢。

2 个答案:

答案 0 :(得分:0)

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

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

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

mov EAX, offset Label2
sub EAX, offset Label1

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

答案 1 :(得分:0)

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

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