1

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

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

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

    mov eax, offset label1
    mov eax, offset label2

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

会不会是搬家造成的?如何推动它通过?

期待解答,谢谢。

4

2 回答 2

0

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

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

于 2012-11-16T17:04:44.440 回答
0

真正的汇编程序在获得所有标签的固定地址之前,可能会多次运行代码。例如,根据您想跳多远,一些跳跃有短形式和长形式。如果标签之间有这样的跳跃,那么距离取决于跳跃的位置。

C 编译器可能会将其中的一些留给链接器/加载器,并且在编译时没有固定值。

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

mov EAX, offset Label2
sub EAX, offset Label1

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

于 2012-11-16T16:56:07.150 回答