GCC- Недопустимое использование регистра

Собираю проект под VS2012 и GCC (CodeBlocks) для Windows. На VS2012 все работает идеально. В GCC я получаю следующую ошибку компиляции:

C:\Users\Piotrek\AppData\Local\Temp\ccfdl0Ye.s|164|Error: invalid use of register|
C:\Users\Piotrek\AppData\Local\Temp\ccfdl0Ye.s|166|Error: invalid use of register|
C:\Users\Piotrek\AppData\Local\Temp\ccfdl0Ye.s|221|Error: invalid use of register|
||=== Build finished: 3 errors, 14 warnings (0 minutes, 0 seconds) ===|

Я использую параметр компилятора -fpermissive - это не должно иметь ничего общего с ошибкой.

Я просто не могу понять, почему он указывает на временный файл в папке Local Temp и говорит, что я использую неправильный регистр ??

Кто-нибудь знает, что происходит?


person filipehd    schedule 25.02.2013    source источник
comment
На самом деле GCC — это не одна программа, это набор программ, которые запускаются одна за другой. Сначала препроцессор, затем собственно компилятор, компилятор генерирует ассемблерный код, который передается ассемблеру, который генерирует объектные файлы, используемые компоновщиком для создания окончательного исполняемого файла. Файл, упомянутый в сообщении об ошибке, является сгенерированным файлом ассемблера. Хотя это не сильно поможет в вашей проблеме, я надеюсь, что это объясняет, почему у вас есть эти временные файлы.   -  person Some programmer dude    schedule 25.02.2013
comment
@JoachimPileborg: для меня это больше похоже на ошибку компилятора. Предупреждения указывают на потенциальные семантические ошибки, но если ошибка генерируется ассемблером, это, вероятно, указывает на ошибку в компиляторе.   -  person Dietrich Epp    schedule 25.02.2013
comment
Моя вторая лучшая ставка заключается в том, что есть несоответствие в флагах, заданных ассемблеру и компилятору, то есть один генерирует код, например. для SSE, и ожидается устаревший набор инструкций x86. Лучше всего, что код содержит директиву asm, то есть VS2012 находится в синтаксисе Intel, а gcc ожидает AT&T. директивы asm передаются как есть на стадию «как».   -  person Aki Suihkonen    schedule 25.02.2013


Ответы (2)


Похоже, вы столкнулись с ошибкой в ​​компиляторе. Сообщения об ошибках (судя по имени "исходного" файла) исходят от ассемблера. Ассемблер должен генерировать сообщение об ошибке только тогда, когда в ассемблере есть что-то недопустимое, а компилятор C++ должен никогда генерировать недопустимый ассемблер; если он не может сгенерировать допустимый ассемблер, он должен вывести сообщение об ошибке и завершиться ошибкой.

Настоящая проблема, когда вы получаете такое сообщение, состоит в том, чтобы выяснить, что в вашем коде вызывает его. В g++ есть опция, которая говорит ему не удалять какие-либо промежуточные файлы. Используйте это, а затем попробуйте посмотреть, что происходит в файлах ассемблера в этих строках. (Когда вы просите g++ вывести ассемблер, он помещает приятные комментарии, помогающие найти соответствующий исходный код. Я не знаю, делает ли он то же самое при создании ассемблера в качестве промежуточного файла.) А затем попробуйте вырезать код (если хуже дойдет до хуже, с помощью бинарного поиска) до тех пор, пока вы не сможете получить ошибку для программы из одной или двух строк. Попробуйте угадать, что в них особенного, и изменить их, чтобы они делали то же самое, но по-другому.

И не забудьте сообщить об ошибке в g++.

person James Kanze    schedule 25.02.2013
comment
Правильно, если только не используется какая-то крутая встроенная сборка (там программист может написать все, что захочет). - person vonbrand; 25.02.2013
comment
James Kanze, вот и все, я решил ее, воспользовавшись вашей рекомендацией. Я опубликую решение как можно скорее - person filipehd; 26.02.2013
comment
Джеймс Канзе, пожалуйста, взгляните на мой ответ, может быть, вы знаете ответ на второй вопрос. Спасибо - person filipehd; 26.02.2013

Благодаря рекомендации Джеймса Канзе я решил сказать компилятору не удалять временные файлы. Это делается флагом:

-сохранение темпов

Как сказал Джеймс, ассемблер генерирует несколько приятных комментариев, которые сообщают, какая именно строка нашего кода на C++ вызывает ошибку. В моем случае похоже, что он не принимает такую ​​​​инструкцию:

asm
(
    ".intel_syntax noprefix\n"
    "lock dec [DWORD PTR eax]\n"
    ".att_syntax \n"
    :
    : "a" (data)
    :
);

Я не знаю, почему он больше не принимает синтаксис Intel, так как он работал с предыдущей версией GCC, а теперь, когда я обновил его, он больше не работает.

Как бы то ни было, решение таких проблем упомянуто Джеймсом: просто не удаляйте промежуточные файлы, чтобы вы могли прямо в ассемблерном коде увидеть, что не так.

Что касается проблемы с синтаксисом INTEL, есть идеи, почему он больше не работает?

person filipehd    schedule 26.02.2013