Инструкция по сборке MIPS bne неправильно выполняется под Microchip XC32
Итак, у меня есть следующий код, скомпилированный в проекте MPLABX с использованием XC32, цель состоит в том, чтобы проверить, нужно ли мне изменить контекст для реализации RTOS:
.extern OS_TaskRUNNING, 0x04 # Both of these are pointers in a C file
.extern OS_TaskNEW, 0x04
CheckSwitch:
la $1, OS_TaskRUNNING
la $2, OS_TaskNEW
lw $1, 0x00($1)
lw $2, 0x00($2)
xor $1, $1, $2
bne $1, $0, ConfirmSwitch
AbortSwitch:
# stuff happens...
ConfirmSwitch:
# stuff happens...
Когда значения в двух указателях различаются, выполнение программы не переходит к ConfirmSwitch, вместо этого оно переходит к AbortSwitch (примечание для невероятно наблюдательных людей: я использую параметр «noat» для кода в этом файле). Ветвление никогда не происходит независимо от того, какие значения заканчиваются в $1 и $2. Я пробовал другие варианты, такие как
bne $1, $2, ConfirmSwitch
и в итоге с тем же результатом. Я не могу понять, что я мог делать неправильно, поскольку эта функциональность настолько проста.
1 ответ
Выяснил это на основе комментариев ниже; добавление nop после каждой инструкции перехода решило проблему. В симуляторе выполнение переходит в nop независимо от того, оценивается ли условие перехода как истинное или нет, но затем переходит в нужное место. Между прочим, я также использовал директиву noreorder, чтобы помешать ассемблеру реорганизовать мой код. В руководстве по ассемблеру XC32 слоты задержки перехода обсуждаются, когда упоминается вышеупомянутая директива: «По умолчанию ассемблер пытается автоматически заполнить слот перехода или задержки, переупорядочив инструкции вокруг него». Это единственное реальное упоминание слота задержки во всем руководстве — нигде не обсуждается, какие инструкции ветвления требуют их или насколько большими они могут быть. Многочисленные примеры кода, которые я нашел в Интернете для решения этой проблемы, не