Как исправить компилятор 68HC11 от создания недопустимых кодов JMP / BRA - PullRequest
0 голосов
/ 18 июня 2019

Я компилирую код 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 при создании двоичного файла.

1 Ответ

0 голосов
/ 25 июня 2019

К сожалению, на этом этапе единственным решением, которое я нашел, был обходной путь для ручного редактирования и исправления сборки, а не окончательное исправление, которое в первую очередь останавливает проблему.

Вот шаги, которые я предпринял, чтобы вручную обойти проблему.

  1. Пересоздай код. Это скомпилирует новые файлы OBJ и свяжет их для создания двоичного (* .BIN) файла
  2. Откройте полученный двоичный файл (* .BIN) в какой-либо форме Hex Editor (я использую HxD)
  3. Поиск следующих шестнадцатеричных значений: 7E0000. 0x7E - это код операции для JMP по абсолютному адресу в 68HC11. Если найдено, продолжайте. Если не найден, код должен быть в порядке
  4. Откройте каждый файл кода (* .C) и скомпилируйте его в файлы сборки (* .AS) и, по желанию, в листинг (* .LST) файлов
  5. Выполните поиск в каждом файле сборки (или списка), чтобы найти BRA 0 (обратите внимание, что в пробеле есть символ табуляции). Найдя, продолжайте
  6. Определите правильную метку, к которой должна быть разветвлена ​​эта линия сборки. Этот шаг может быть довольно сложным, и я сначала использовал неправильный ярлык.
  7. Откройте файл сборки с ошибочным BRA 0 в нем и измените его на ветвь с правильной меткой, т.е. BRA L8
  8. Если файл Assembly все еще открыт, скомпилируйте его в файл Object (* .OBJ). Это будет использовать обновленную (и, надеюсь, правильную) метку ветки
  9. Сделайте код. Не переделывать . Это обнаружит, что изменился только новый объектный файл, и будет использовать его для создания нового двоичного файла. На этот раз у него не будет ошибочного JMP0000
  10. По выбору (, но рекомендуется ) проверьте получившийся двоичный файл (* .BIN), чтобы убедиться, что он больше не имеет шестнадцатеричных значений 7E0000
...