如何通过制作无效的JMP / BRA代码来修复68HC11编译器

时间:2019-06-18 06:39:31

标签: c assembly opcode 68hc11 hi-tech-c

我正在编译用于为设备的EPROM编程的C代码。使用的编译器是Hi-Tech C编译器。我相信它是7.80版。

当我(重新)编写代码时,它会生成一个二进制(* .BIN)文件,该文件将刷新到EPROM。

我发现编译后的代码通常在汇编中只包含一行,这会破坏代码并使设备在到达时就关闭。似乎编译器正在更改“始终分支”(BRA)语句以错误地执行BRA 0,该语句在转换为十六进制操作码时会被编译器转换为JMP 0000。这会导致代码到达代码的意外区域,从而导致设备关闭。

重新制作代码时,此错误分支始终位于同一位置。但是我发现,如果我对代码进行少量更改,则不同的BRA调用会得到完全相同的损坏。

现在,我感觉需要挖掘* .BIN文件本身,找到错误的BRA / JMP调用,然后手动进行修复。问题是,每当我更改代码然后创建新的Binary文件时,我都需要跟踪这个错误的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列表文件。

 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 0JMP 0000不同,但是编译器出于未知原因(1)将BRA 0放在Assembly文件而不是{{1 }}的内容,然后(2)在创建二进制文件时将其转换为BRA l28

1 个答案:

答案 0 :(得分:0)

不幸的是,在此阶段,我发现的唯一解决方案是一种手动编辑和修复Assembly的变通方法,而不是确定性的解决方案,该解决方案首先阻止了该问题的发生。

这是我手动解决此问题所采取的步骤。

  1. 重新制作代码。这将编译新的OBJ文件并将其链接以创建二进制(* .BIN)文件
  2. 在某种形式的十六进制编辑器(我使用HxD)中打开生成的二进制文件(* .BIN)
  3. 搜索以下十六进制值:7E0000。 0x7E是JMP到68HC11中的绝对地址的操作码。如果找到,请继续。如果找不到,则代码应该没问题
  4. 打开每个代码文件(* .C),将其编译为汇编(* .AS)文件,还可以将其编译为清单(* .LST)文件
  5. 在每个Assembly(或Listing)文件中搜索以找到BRA 0(请注意,空格处带有制表符)。找到后,继续
  6. 确定该装配线应分支到的正确标签。这一步可能很困难,我刚开始使用错误的标签。
  7. 打开其中包含错误BRA 0的Assembly文件,然后将其更改为分支到正确的标签,即BRA L8
  8. 在Assembly文件仍然打开的情况下,将其编译为Object(* .OBJ)文件。这将使用更新的(希望是正确的)分支标签
  9. 制作代码。 请勿重新制作。这将表明只有新的Object文件已更改,并将使用它来创建新的Binary文件。这次它将没有错误的JMP0000
  10. (可选,但建议)检查生成的二进制(* .BIN)文件,以确保该文件不再具有十六进制值7E0000