Вставка комментария в __asm ​​приводит к ошибке C2400 (VS2012)

Я пытался проверить скомпилированный ассемблер некоторого кода в VS 2012. Я добавил две строки (до и после моего кода) как таковые:

__asm ; it begins here!
// My code
__asm ; it ends here!

Однако VS не понравилось это. я получил

ошибка C2400: ошибка синтаксиса встроенного ассемблера в ‘код операции’; найден «плохой токен»

Поэтому я добавил NOPчто я не хотел:

__asm NOP ; Comment!

Это работало нормально. Мой вопрос двоякий.

  1. Почему VS не позволил мне добавить комментарий сборки?
  2. Есть ли другой способ добавить комментарий сборки без добавления инструкции, в том числе NOP?

1

Решение

Причина, по которой это не работает, заключается в том, что __asm это ключевое слово, так же, как int является ключевым словом, оно не может появляться само по себе и должно следовать правильному синтаксису. Возьмем следующий фрагмент кода в качестве примера:

int main()
{
int      // here's a comment, but it's ignored by the compiler
return 0;
}

Следующий код потерпит неудачу с ошибкой компиляции, более конкретно в VS2012 вы получите error C2143: syntax error : missing ';' before 'return', Это очевидная ошибка, поскольку у нас нет конечной точки с запятой для обозначения конца инструкции; добавьте точку с запятой, и она прекрасно скомпилируется, потому что мы не нарушали синтаксис языка C (или C ++ в данном случае):

int main()
{
int      // here's a comment, but it's ignored by the compiler
; // white space and comments are ignored by the compiler
return 0;
}

То же самое относится и к следующему коду:

int main()
{
__asm ; here's a comment but it's ignored

return 0;
}

Кроме здесь мы получаем ошибку error C2400: inline assembler syntax error in 'opcode'; found 'constant'потому что это лечит все после __asm Ключевое слово в качестве инструкции на ассемблере, и комментарий по праву игнорируется .. поэтому будет работать следующий код:

int main()
{
__asm ; here's a comment but it's ignored
NOP ; white space and comments are ignored by the compiler

__asm {; here's an __asm 'block'
} // outside of __asm block so only C style comments work
return 0;
}

Так что это отвечает на ваш первый вопрос: Why didn't VS allow me to add an assembly comment?.. потому что это является синтаксическая ошибка.

Теперь для вашего второго вопроса: Is there a different way to add an assembly comment without adding an instruction, including NOP?

Прямо нет, нет, но косвенно да есть. Стоит отметить, что __asm Ключевое слово компилируется во встроенную сборку в вашей программе, поэтому комментарии будут удаляться из скомпилированной сборки так же, как если бы это был стандартный комментарий C / C ++, поэтому пытаться «принудительно» вызвать комментарий в вашей сборке с помощью этого метода, вместо этого , вы можете использовать /FAs флаг компилятора, и он сгенерирует сборку (машинный код), смешанную с исходным кодом, например:

Учитывая следующий (очень простой) код:

int main()
{
// here's a normal comment
__asm { ; here's an asm comment and empty block
} // here's another normal comment
return 0;
}

Когда скомпилировано с /FAs флаг компилятора file.asm было получено следующее:

; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.31101.0

TITLE   C:\test\file.cpp
.686P
.XMM
include listing.inc
.model  flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  _main
; Function compile flags: /Odtp
; File c:\test\file.cpp
_TEXT   SEGMENT
_main   PROC

; 2    :     {

push    ebp
mov ebp, esp

; 3    :         // here's a normal comment
; 4    :         __asm { ; here's an asm comment and empty block
; 5    :         } // here's another normal comment
; 6    :         return 0;

xor eax, eax

; 7    :     }

pop ebp
ret 0
_main   ENDP
_TEXT   ENDS
END

Обратите внимание, как он включает в себя источник и комментарии. Если бы этот код сделал больше, вы бы увидели больше ассемблера и связанный с ним источник.

Если вы хотите поместить комментарии в саму встроенную сборку, то вы можете использовать обычные комментарии в стиле C / C ++, а также комментарии сборки внутри __asm сам блок:

int main()
{
// here's a C comment
__asm { ; here's an asm comment
// some other comments
NOP ; asm type comment
NOP // C style comment
} // here's another comment
return 0;
}

Надеюсь, что это может помочь.

РЕДАКТИРОВАТЬ:

Следует отметить, что следующий фрагмент кода также компилируется без ошибок, и я не уверен на 100%, почему:

int main()
{
__asm
__asm ; comment
// also just doing it on a single line works too: __asm __asm
return 0;
}

Компиляция этого кода с единственным __asm ; comment выдает ошибку компиляции, но с обоими компилирует нормально; добавление инструкций к приведенному выше коду и проверка .asm выход показывает, что второй __asm игнорируется для любых других команд сборки, предшествующих ему. Так что я не уверен на 100%, если это ошибка синтаксического анализа или часть __asm Синтаксис ключевого слова, так как нет документации по этому поведению.

2

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector