Есть какие-нибудь хорошие программисты на 68k ассемблере ?? Я использую коммерческий компилятор Green Hills для Motorola 68040 и вижу очень странное поведение кода. Иногда код выполняет сравнение if / else и выбирает неправильную ветвь. Например:
float a = 1, b = 2;
if (a < b)
do c;
else
do d;
Иногда код будет d !? Я обнаружил, что всякий раз, когда возникает эта ошибка, всегда есть одна конкретная ISR, которая прерывает сравнение. Я взглянул на сгенерированную сборку для ISR и увидел несколько вещей, которые не имеют для меня смысла. Во-первых, похоже, что регистры состояния с плавающей запятой, FPSR, FPCR и FPIAR, не сохраняются в ISR. Это могло бы объяснить, почему if / elses выбирают неправильную ветвь. Регистр FPSR используется для определения результата сравнения, и если этот регистр перезаписывается в ISR, ветвь может пойти по неправильному пути. Ниже приводится сборка входа и выхода, созданная компилятором:
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
Я просмотрел Справочное руководство программиста и не нашел ничего, что предполагало бы, что FSAVE или FMOVEM сохраняет регистры состояния FP. На самом деле, я видел один комментарий, который предполагает, что это не так: «FSAVE не сохраняет регистры модели программиста модуля с плавающей запятой; он сохраняет только невидимую для пользователя часть машины."Итак, я добавил некоторую собственную сборку, чтобы сохранить регистры в начале ISR и восстановить их в конце, и это значительно улучшило производительность, но я все еще вижу некоторые проблемы. Ниже приведены внесенные мной дополнения. ; переменные резервного копирования набираются как unsigned long в коде C:
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
FMOVE %FPIAR,fpiar_backup
FMOVE %FPSR,fpsr_backup
FMOVE %FPCR,fpcr_backup
; isr code ...
FMOVE fpiar_backup,%FPIAR
FMOVE fpsr_backup,%FPSR
FMOVE fpcr_backup,%FPCR
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
Мне было трудно поверить, что компилятор действительно имел ошибку, не сохраняя регистры. Поэтому я начал смотреть на значения FPx и Dx, чтобы убедиться, что они восстанавливаются до правильного значения, и похоже, что это не так. Однако я не на 100% уверен, что не испортил код сборки своими модификациями. Ниже приведен код, который я добавил для сохранения регистров; переменные отладки набирается как unsigned longs:
isr_function:
FMOVE %FP0,debug3
FMOVE %FP1,debug5
FMOVE %FP2,debug7
FMOVE %FP3,debug9
FMOVE %FP4,debug11
FMOVE %FP5,debug13
FMOVE %FP6,debug15
FMOVE %FP7,debug17
FMOVE %FPCR,debug19
FMOVE %FPIAR,debug23
FMOVE %FPSR,debug25
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FMOVE %FP0,debug4
FMOVE %FP1,debug6
FMOVE %FP2,debug8
FMOVE %FP3,debug10
FMOVE %FP4,debug12
FMOVE %FP5,debug14
FMOVE %FP6,debug16
FMOVE %FP7,debug18
FMOVE %FPCR,debug20
FMOVE %FPIAR,debug24
FMOVE %FPSR,debug26
FRESTORE (%SP)+
RTE
Короче говоря, мои вопросы:
1) есть ли проблема со сгенерированной сборкой в том, что она не сохраняет регистры FPSR, FPCR и FPIAR, и
2) я правильно сохранять значения регистров, когда я вхожу в ISR и выхожу из него?
Было бы здорово, если бы у меня был другой компилятор сравнивать с. К сожалению, я не могу подключить к коду отладчик. У меня большой опыт работы с C / C ++ / C # / Java / Python / PHP / и т. Д., Но я далек от специалиста по сборке.
Любые идеи приветствуются!