|
C+ASM - помогите, Не понимаю, чего ему не нравится |
|
|
|
Mar 5 2008, 05:45
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Всем приветы! Ткскзть двое суток без сна, не могу победить простую вещь. Имеется IAR 4.41, пытаюсь сделать ассемблерную вставку, не выходит: Код static inline portDISABLE_INTERRUPTS(void) { asm (" STMDB SP!, {R0}"); asm (" MRS R0, CPSR"); asm (" ORR R0,R0,#0x80"); asm (" MSR CPSR,R0"); asm (" LDMIA SP!, {R0}"); } В ответ получаю Код Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" c:\PTJoy\new\firmware\ptjoy\FreeRTOS\Source\portable\IAR\SAM7S256\portmacro.h 93 Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" c:\PTJoy\new\firmware\ptjoy\FreeRTOS\Source\portable\IAR\SAM7S256\portmacro.h 94 Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" c:\PTJoy\new\firmware\ptjoy\FreeRTOS\Source\portable\IAR\SAM7S256\portmacro.h 95 По-хорошему, нужно делать #define'ом, но там то-же самое, только без номеров строк Ткните пожалуйста, что я делаю не так. Процессор - ARM7. Спасибо!
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 17)
|
Mar 5 2008, 06:31
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Код asm (" MRS R0, CPSR"); asm (" ORR R0,R0,#0x80"); asm (" MSR CPSR,R0"); В этих командах у Вас ошибка синтаксиса, посмотрите manual.
|
|
|
|
|
Mar 5 2008, 06:46
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(tag @ Mar 5 2008, 09:31)  В этих командах у Вас ошибка синтаксиса, посмотрите manual. Смотрю ассемблерный листинг, сгенерированный этим-же компилятором: Код vPortEnterCritical: MRS R0,CPSR ORR R0,R0,#0xC0 MSR CPSR_c,R0 и не вижу разницы...
|
|
|
|
|
Mar 5 2008, 07:05
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Ассемблерную строку надо заканчивать символом \n См. в описании компилятора главу INLINE ASSEMBLER. Пример из описания: Код bool flag; void foo() { while (!flag) { asm(" ldr r2,[pc,#0] \n" /* r2 = address of flag */ " b .+8 \n" /* jump over constant */ " DCD flag \n" /* address of flag */ " ldr r3,[pc,#0] \n" /* r3 = address of PIND */ " b .+8 \n" /* jump over constant */ " DCD PIND \n" /* address of PIND */ " ldr r0,[r3] \n" /* r0 = PIND */ " str r0,[r2]"); /* flag = r0 */ } } Хотя может и не в этом дело.
|
|
|
|
|
Mar 5 2008, 07:08
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(IgorKossak @ Mar 5 2008, 10:05)  Ассемблерную строку надо заканчивать символом \n См. в описании компилятора главу INLINE ASSEMBLER. Да пробовал и с \n: Код static inline portDISABLE_INTERRUPTS(void) { asm (" STMDB SP!, {R0}\n"); asm (" MRS R0, CPSR\n"); asm (" ORR R0,R0,#0x80\n"); asm (" MSR CPSR,R0\n"); asm (" LDMIA SP!, {R0}\n"); } Ошибки те-же в тех-же местах. ЗЫ большие-маленькие мнемоники я тоже пробовал, и названия регистров тоже
|
|
|
|
|
Mar 5 2008, 07:15
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(Kitsok @ Mar 5 2008, 12:08)  Ошибки те-же в тех-же местах. а у меня ваш код без проблем откомпилировался: Код # IAR ARM ANSI C/C++ Compiler V4.41A/W32 EVALUATION 05/Mar/2008 12:09:03 # \ In segment CODE, align 4, keep-with-next 266 void portDISABLE_INTERRUPTS(void) 267 { 268 asm (" STMDB SP!, {R0}"); \ ??portDISABLE_INTERRUPTS: \ 00000000 01002DE9 STMDB SP!, {R0} 269 asm (" MRS R0, CPSR"); \ 00000004 00000FE1 MRS R0, CPSR 270 asm (" ORR R0,R0,#0x80"); \ 00000008 800080E3 ORR R0,R0,#0x80 271 asm (" MSR CPSR,R0"); \ 0000000C 00F029E1 MSR CPSR,R0 272 asm (" LDMIA SP!, {R0}"); \ 00000010 0100BDE8 LDMIA SP!, {R0} 273 } \ 00000014 0EF0A0E1 MOV PC,LR ;; return А почему вы не хотите: Код void portDISABLE_INTERRUPTS_1(void) { __set_CPSR(__get_CPSR() | 0x80); } ?
--------------------
Пасу котов...
|
|
|
|
|
Mar 5 2008, 07:31
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(IgorKossak @ Mar 5 2008, 10:21)  Взял Вашу функцию один к одному, скомпилировал, ни одной ошибки. Правда у меня версия 5.11, но не думаю, чтобы так сильно всё отличалось.
Нашел в чём дело. Если в настройках компилятора устанавливаю Code->Processor mode->Thumb, то возникает ошибка 401. С ARM всё нормально. Вот похоже, что в этом и дело. В итоге вот так скомпилялось, а работает или нет - буду проверять Код __arm __interwork static inline __disable_IRQ( void );
__arm __interwork static inline __disable_IRQ(void) { asm (" stmdb SP!, {r0}\n"); asm (" mrs r0, CPSR\n"); asm (" orr r0,r0,#0x80\n"); asm (" msr CPSR,r0\n"); asm (" ldmia SP!, {r0}\n"); }
#define portDISABLE_INTERRUPTS() __disable_IRQ()
|
|
|
|
|
Mar 5 2008, 07:35
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
более правильный код для запрещения прерываний на АРМ такой: Код do { __set_CPSR(StatusReg | (1<<7)); } while (!(__get_CPSR() & (1<<7)));
--------------------
Пасу котов...
|
|
|
|
|
Mar 5 2008, 07:54
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Andy Mozzhevilov @ Mar 5 2008, 10:35)  более правильный код для запрещения прерываний на АРМ такой: Код do { __set_CPSR(StatusReg | (1<<7)); } while (!(__get_CPSR() & (1<<7))); Дык у меня thumb, а __?et_CPSR - intrinsic, поэтому, видимо, все функции, вызывающие такой запрет нужно компилять с __intrinsic. А в чем разница с моим-то?  Вон, родной __disable_interrupt вообще даже R0 в стеке не сохраняет.
|
|
|
|
|
Mar 5 2008, 10:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Andy Mozzhevilov @ Mar 5 2008, 09:35)  более правильный код для запрещения прерываний на АРМ такой: Еще более оптимальный такой (исправлен): Код while (!(__get_CPSR() & (1<<7))) { __set_CPSR(StatusReg | (1<<7)); } Цитата(Andy Mozzhevilov @ Mar 5 2008, 10:15)  Не могу сейчас быстро найти соответсвующий раздел документации. Atmel Application Note Rev. 1156A-08/98Цитата(Kitsok @ Mar 5 2008, 09:54)  Дык у меня thumb, а __?et_CPSR - intrinsic, поэтому, видимо, все функции, вызывающие такой запрет нужно компилять с __intrinsic. Доступ к CPSR имеют только команды ARM-режима (MSR, MRS). Из THUMB режима могут быть вызваны ARM-функции, скомпилированные с атрибутом __interwork. __intrinsic - ключевое слово для функций, реализованных внутри компилятора (для которых компилятор генерит код сам в процессе компиляции) и не должно использоваться для пользовательских функций. Генерируемый для __intrinsic - функций код может отличаться в зависимости от аргументов, режима компиляции и кучи других параметров. Для той же __disable_interrupt() в ARM-режиме генерится непосредственно MSR, MCR, а в THUMB-режиме - вызов соответствующей ARM-функции.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 5 2008, 11:33
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Вот на этом while'е оно и встанет  Точка с запятой там явно лишняя. Да, __intrinsic перепутал естественно с __interwork. Вроде работает, спасибо! Начинаем битву с FIQ, но это уже тема совсем другого топика
|
|
|
|
|
Mar 5 2008, 12:41
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Kitsok @ Mar 5 2008, 13:33)  Вот на этом while'е оно и встанет  Точка с запятой там явно лишняя. Угу. Делал быстро из кода Andy, упустил. Цитата(repairDV @ Mar 5 2008, 14:35)  А этот ассемблер, который внутри процедуры Си, полнофункциональный? Условные - безусловные переходы на метки поддерживает? Нет. Это даже не ассемблер, а так, некий костыль чтобы вставить NOP. Даже в документации написано что-то вроде "ну есть нечто похожее на ассемблер, но лучше и не пытайтесь его использовать  ". В этом смысле инлайн-ассемблер GCC - просто произведение искусства.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 5 2008, 14:04
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ) Цитата(repairDV @ Mar 5 2008 @ 14:35) А этот ассемблер, который внутри процедуры Си, полнофункциональный? Условные - безусловные переходы на метки поддерживает? Нет. Это даже не ассемблер, а так, некий костыль чтобы вставить NOP. Странно. У меня поддерживал всегда. Постоянно оптимизированные циклы строчил на асме. IAR 4.20.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Mar 5 2008, 14:15
|

Знающий
   
Группа: Свой
Сообщений: 578
Регистрация: 7-11-06
Из: Хабаровск
Пользователь №: 22 044

|
Цитата(GetSmart @ Mar 6 2008, 00:04)  Странно. У меня поддерживал всегда. Постоянно оптимизированные циклы строчил на асме. IAR 4.20. Это хорошо. У меня, правда, IAR для NEC. Простеньких, только для датчиков давления. Но, может быть, придётся по-серьёзному с ним работать. Для примера: CodeWarrior позволяет писать полнофункциональные программы в ассемблере внутри Си-функций. Очень удобно. Стиль написания приблизительно похож на тот, который здесь приводился.
--------------------
Маленький нанайца. А-а. А-а. Оморочком плыл. Маленький проточка. Осетра ловил.
|
|
|
|
|
Mar 5 2008, 15:44
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Mar 5 2008, 16:04)  Нет. Это даже не ассемблер, а так, некий костыль чтобы вставить NOP.Странно. У меня поддерживал всегда. Постоянно оптимизированные циклы строчил на асме. IAR 4.20. Ну, я собственно пересказал вот это: Цитата Inline assembler sequences have no well-defined interface with the surrounding code generated from your C or C++ code. This makes the inline assembler code fragile, and will possibly also become a maintenance problem if you upgrade the compiler in the future. In addition, there are several limitations to using inline assembler: ● The compiler’s various optimizations will disregard any effects of the inline sequences, which will not be optimized at all ● The directives CODE16 and CODE32 will cause errors; several other directives cannot be used at all ● Alignment cannot be controlled; this means, for example, that DC32 directives may be misaligned ● Auto variables cannot be accessed ● Alternative register names, mnemonics, and operators are not supported; read more about the -j assembler option in the ARM® IAR Assembler Reference Guide. Inline assembler is therefore often best avoided. If there is no suitable intrinsic function available, we recommend the use of modules written in assembler language instead of inline assembler, because the function call to an assembler routine normally causes less performance reduction. Интересно, чем "will cause errors" отличается от "cannot be used at all"  Про метки и переходы я, похоже, погорячился.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|