Visual-C ++ встроенная ассемблерная разница двух смещений

Я переношу кусок кода с MASM на C inline ассемблер (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 

Я ожидаю, что компилятор будет оценивать (смещение label1 – offset label2) во время компиляции, но похоже, что я ошибаюсь. Я также не могу добавить смещения (почему? Это всего лишь два целых числа, добавленные во время компиляции …?) Конечно, я могу получить mov eax, смещение label2 mov edx, offset label1 sub eax, edx скомпилировано, но это дополнительный код просто для вычисления константы. Может кто-нибудь объяснить мне, пожалуйста, что не так в моем коде?

Может ли это быть причиной перемещения? Как пробить его?

Ждем ответа, спасибо.

Да, это может быть вызвано угрозой перемещения, но также и угрозой инструкций переменной длины относительно относительных прыжков. Скорее всего, из-за каких-то незначительных проблем авторы ассемблера легко вышли и реализовали компилятор с 1 пропускным или двухпроходным протоколом, который принимает окончательные решения как можно скорее. И, следовательно, некоторые удобные выражения не поддерживаются.

Как уже было сказано в комментарии, ассемблер, по-видимому, поддерживает поддержку mov + sub.

Настоящий ассемблер, вероятно, работает над кодом за несколько проходов, прежде чем он получит фиксированные адреса для всех меток. Например, некоторые прыжки имеют короткую и длинную форму в зависимости от того, как далеко вы хотите прыгать. Если у вас есть такой прыжок между ярлыками, расстояние зависит от того, куда будет идти прыжок.

Компилятор C может оставить некоторые из них компоновщику / загрузчику и не иметь значений, зафиксированных во время компиляции.

Вы вполне можете получить код расчета addres до двух инструкций

 mov EAX, offset Label2 sub EAX, offset Label1 

Я не думаю, что это точно испортит производительность кода.