簡體   English   中英

如何修復68HC11編譯器制作無效的JMP / BRA代碼

[英]How to fix 68HC11 Compiler from making invalid JMP/BRA codes

我正在編譯用於為設備編程EPROM的C代碼。 正在使用的編譯器是Hi-Tech C編譯器。 我相信它是版本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,以避免混淆。它是在匯編代碼中定義得較低的標簽,其中這個分支應該去)。

這導致以下十六進制操作碼:

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放入匯編文件而不是BRA l28 ,這應該是什么,以及(2)轉換它創建二進制文件時到JMP 0000

不幸的是,在這個階段,我找到的唯一解決方案是手動編輯和修復程序集的解決方法,而不是一個能夠阻止問題首先發生的確定性修復。

以下是我手動解決此問題的步驟。

  1. 重新制作代碼。 這將編譯新的OBJ文件並鏈接它們以創建二進制(* .BIN)文件
  2. 在某種形式的十六進制編輯器中打開生成的二進制文件(* .BIN)(我使用HxD)
  3. 搜索以下十六進制值: 7E0000 0x7E是JMP到68HC11中的絕對地址的操作碼。 如果找到,繼續。 如果沒有找到,代碼應該沒問題
  4. 打開每個代碼文件(* .C)並將它們編譯為Assembly(* .AS)文件和可選的Listing(* .LST)文件
  5. 搜索每個Assembly(或Listing)文件以查找BRA 0 (請注意,空格中有一個制表符)。 一旦找到,繼續
  6. 確定此行程序集應分支的正確標簽。 這一步可能非常困難,我最初使用的是錯誤的標簽。
  7. 打開裝配文件,其中包含錯誤的BRA 0 ,並將其更改為分支到正確的標簽,即BRA L8
  8. 在Assembly文件仍然打開的情況下,將其編譯為Object(* .OBJ)文件。 這將使用更新的(並且希望是正確的)分支標簽
  9. 制作代碼。 不要重新制作 這將獲取只有新的Object文件已更改,並將使用它來創建新的二進制文件。 這次它不會有錯誤的JMP0000
  10. (可選)( 但建議 )檢查生成的二進制(* .BIN)文件,以確保它不再具有十六進制值7E0000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM