Я пытался проверить скомпилированный ассемблер некоторого кода в VS 2012. Я добавил две строки (до и после моего кода) как таковые:
__asm ; it begins here!
// My code
__asm ; it ends here!
Однако VS не понравилось это. я получил
ошибка C2400: ошибка синтаксиса встроенного ассемблера в ‘код операции’; найден «плохой токен»
Поэтому я добавил NOP
что я не хотел:
__asm NOP ; Comment!
Это работало нормально. Мой вопрос двоякий.
NOP
?Причина, по которой это не работает, заключается в том, что __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
Синтаксис ключевого слова, так как нет документации по этому поведению.