Я компилирую код C для программирования EPROM для устройства.Используемый компилятор - это Hi-Tech C Compiler.Я полагаю, что это версия 7.80.
Когда я (повторно) создаю свой код, он создает двоичный файл (* .BIN) для перепрошивки в EPROM.
Я обнаружил, чтоскомпилированный код часто поставляется с одной строкой в сборке, которая нарушает код и приводит к отключению устройства при его достижении.Похоже, что компилятор изменяет оператор Branch-Always (BRA) на ошибочно делать BRA 0
, который при преобразовании в шестнадцатеричные коды операций преобразуется компилятором в JMP 0000
.Это приводит к тому, что код достигает неожиданной области кода, и, следовательно, устройство отключается.
При повторном создании кода эта ошибочная ветвь всегда находится в одном и том же месте.Однако я обнаружил, что, если я внесу небольшие изменения в код, другой вызов BRA получит точно такое же повреждение.
Я сейчас нахожусь в той точке, когда мне кажется, что мне нужно копаться в самом файле * .BINнайдите ошибочный вызов BRA / JMP и исправьте его вручную.Проблема заключается в том, что всякий раз, когда я делаю изменения в коде, а затем создаю новый двоичный файл, мне нужно будет отследить этот ошибочный вызов BRA / JMP, вычислить, какими будут правильные коды операций для вызова BRA, который должен быть там,и отредактируй это сам.Я бы предпочел не делать это каждый раз, когда вносил изменения, так как это может занять много времени.
Вот пример ошибочного вызова BRA и кода вокруг него.Извините, но я не могу предоставить полный исходный код для этого, так как это для проприетарной системы, но я могу поделиться сборкой и шестнадцатеричными кодами по этому вопросу.
Эквивалентный код C с добавлением примечания о том, где ошибочный BRAПроисходит / JMP:
if ( variable > 5.5 )
{
printf( "Variable is: %f", variable );
// right here is where the BRA 0 is in the Assembly (JMP 0000 in hex). It should be branching to function_call() below, but it is not
}
else
{
if ( variable < 5.4 )
{
// bunch of code in here
}
else
{
// if/else in here with some printf() calls
}
}
function_call();
Это из скомпилированного файла сборки * .AS:
tsy
ldx 3,y
pshx
ldx 1,y
pshx
ldx #u189
bra 0
Указанная выше bra 0
сборка недопустима.В данном конкретном случае, согласно меткам в файле Assembly, оно должно быть bra l28
(обратите внимание, что это L28 с строчной буквой L, чтобы избежать путаницы. Это метка, которая определена ниже в коде Assembly,куда должна идти эта ветвь).
В результате получается следующий шестнадцатеричный код операции:
18 30 CD EE 03 3C CD EE 01 3C CE F6 DD 7E 00 00
Следующая выдержка из файла * .LST Listing.
758 03E0' 18 30 tsy
759 03E2' CD EE 03 ldx 3,y
760 03E5' 3C pshx
761 03E6' CD EE 01 ldx 1,y
762 03E9' 3C pshx
763 03EA' CE 005D' ldx #u189
764 03ED' 7E 0000 bra 0
Как видно, он преобразует bra 0
в JMP 0000
(7E 0000).
Я хотел бы найти решение, которое окончательно разрешит эту ситуацию так, что компилятор больше не будет поврежденслучайная мнемоника BRA в сборке, которая не требует, чтобы я копал двоичный файл, находил вызов JMP и вручную исправлял его каждый раз, когда меняю код.
Чтобы уточнить, я понимаю, что BRA 0
не то же самое, что JMP 0000
, однако по неизвестным причинам компилятор (1) помещает BRA 0
в файл сборки вместо BRA l28
, как это должно быть, и (2) преобразует это в JMP 0000
при создании двоичного файла.