Компилятор IAR 7.40 генерирует неверную сборку
У меня есть встроенный код ассемблера для arm cortex-R5
#include <stdio.h>
#define mtcpsr(v) __asm volatile(\
"msr cpsr,%0\n"\
: : "r" (v)\
)
int mfcpsr (void)
{
int rval;
asm("mrs %0, cpsr" : "=r"(rval));
return rval;
}
void main(void)
{
/*
* Enable interrupts in the ARM
*/
mtcpsr(mfcpsr() & ~ ((0x80U) & (0x40U | 0x80U)));
}
Это при компиляции с компилятором IAR 7.40 в режиме Thumb путем установки --cpu_mode=thumb в качестве флага компилятора, генерирует сборку как
`.text6`:
mfcpsr:
0xfffc040c: 0xf3ef 0x8000 MRS R0, APSR
0xfffc0410: 0x4770 BX LR
0xfffc0412: 0x0000 MOVS R0, R0
main:
0xfffc0414: 0xb580 PUSH {R7, LR}
0xfffc0416: 0xf7ff 0xfff9 BL mfcpsr ; 0xfffc040c
0xfffc041a: 0xf020 0x0080 BIC.W R0, R0, #128 ; 0x80
0xfffc041e: 0xf380 0x8000 MSR ??-0-0, R0
0xfffc0422: 0xbd01 POP {R0, PC}
MSR??-0-0, R0 - неверная сборка. Я ожидаю его как MSR CPSR_fc, R0 (который я получил без опции большого пальца). Можете ли вы, ребята, помочь мне найти проблему.
1 ответ
Синтаксис инструкции MSR в вашем коде неверен. Инструкция MSR требует, чтобы к имени регистра состояния, в вашем случае CPSR, добавлялись поля, которые должны быть обновлены. Поэтому, если вы измените макрос mtcpsr на следующий, вы получите ожидаемый результат
#define mtcpsr(v) __asm volatile(\
"msr CPSR_cxsf,%0\n"\
: : "r" (v)\
)
Я могу только догадываться, почему компилятор ведет себя по-разному в режиме "большой руки" и "большой палец" или почему он не выдает предупреждение, но это, вероятно, ошибка.
В качестве примечания: если вы хотите включить только прерывания, вы можете использовать CPSIE if
инструкция или __enable_interrupts()
внутренняя функция.