首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何修复68HC11编译器产生无效的JMP/BRA代码

如何修复68HC11编译器产生无效的JMP/BRA代码
EN

Stack Overflow用户
提问于 2019-06-18 14:39:32
回答 1查看 106关注 0票数 0

我正在编译用于为设备编写EPROM的C代码。正在使用的编译器是高科技C编译器。我相信它是7.80版本。

当我(重新)编写代码时,它会生成一个二进制(*.BIN)文件,用于闪存到EPROM中。

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

当重新编写代码时,这个错误的分支总是在同一位置。然而,我发现如果我对代码做了一些小的修改,一个不同的胸罩调用就会得到完全相同的损坏。

我现在觉得我需要深入研究*.BIN文件本身,找到错误的BRA/JMP调用,并手动修复它。这样做的问题是,每当我对代码进行更改,然后创建一个新的二进制文件时,我将需要跟踪这个错误的BRA/JMP调用,计算应该存在的BRA调用的正确操作码,然后自己编辑它。我不希望每次进行更改时都要这样做,因为这可能会占用很多时间。

这是一个错误的胸罩调用的例子和它周围的代码。我很抱歉,但我不能提供完整的源代码,因为它是一个专有系统,但我可以分享汇编和十六进制代码围绕这个问题。

等效的C代码,并添加了错误的BRA/JMP发生位置的注释:

代码语言:javascript
复制
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程序集文件:

代码语言:javascript
复制
    tsy
    ldx 3,y
    pshx
    ldx 1,y
    pshx
    ldx #u189
    bra 0

上述bra 0程序集无效。在这种特殊情况下,根据程序集文件中的标签,它应该是bra l28 (注意,这是L28,带有小写的L,以避免混淆。这是一个在汇编代码中定义较低的标签,应该是这个分支的位置)。

这将产生以下十六进制操作码:

代码语言:javascript
复制
18 30 CD EE 03 3C CD EE 01 3C CE F6 DD 7E 00 00 

以下摘录来自*.LST清单文件。

代码语言:javascript
复制
 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放在汇编文件中,而不是应该放在BRA l28中,以及(2)在创建二进制文件时将其转换为JMP 0000

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-25 08:54:01

不幸的是,在这个阶段,我找到的唯一解决方案是手动编辑和修复程序集,而不是从一开始就阻止问题发生的最终解决方案。

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

  1. 重新编写代码。这将编译新的OBJ文件并链接它们以创建二进制(*.BIN)文件
  2. 在某种形式的十六进制编辑器(我使用HxD)中打开结果二进制文件(*.BIN)
  3. 搜索以下十六进制值:7E0000。0x7E是68HC11中JMP到绝对地址的操作码。如果找到,请继续。如果找不到,代码应该是
  4. 打开每个代码文件(*.C)并将它们编译成程序集(*.AS)文件和可选的列表(*.LST)文件
  5. 搜索每个程序集(或列表)文件以查找BRA 0 (请注意,空格中有一个制表符)。找到后,continue
  6. Determine此装配线应分支到的正确标签。这一步可能相当困难,一开始我使用了错误的标签。
  7. 打开包含错误BRA 0的程序集文件,并将其更改为分支到正确的标签,例如,将程序集文件仍然打开,将其编译为对象(*.OBJ)文件。这将使用更新的(希望是正确的)分支label
  8. Make代码。不会重新生成。这将发现只有新的对象文件发生了更改,并将使用它来创建新的二进制文件。这一次,它将不会让错误的JMP0000
  9. Optionally (但建议)检查生成的二进制( 7E0000

)文件,以确保它不再具有十六进制值*.BIN

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56643061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档