2012-02-19 8 views
2

ファームウェアmodを書き込もうとしています(既存のファームウェアには、ソースコードがありません) すべてのThumbコード。ファームウェアパッチのためのARM/Thumbコード... gccアセンブラ/リンカをBLへの絶対アドレスへの通知方法?

誰もが、これを行うにはどのように任意のアイデアを持っているgcc as中(GAS)アセンブラん: 使用BL手動でオフセットを計算することなく、BLは「(ない私のコードでは、いくつかの既存の機能にする際に..しかし、私現在

に)そのアドレスを知っている私はBLを使用したい場合は、...私が持っている: は私のコードに戻って - 図を-GOとのすべての前の命令をアセンブルすることから生じるすべてのバイトを追加関数私は書いています - 私の関数の最初のアドレスを追加します(私は指定します私が書いているものの開始アドレス)を とし、電話をかけたいfirmfunc関数のアドレスを差し引く

すべてこれは...できるだけオフセットを計算することです既存のファームウェア機能を呼び出すためにblオフセットを書き込むには? そして、私はそのBLの前にコードを変更したら、私はそれを再び手でやり直さなければなりません!
は、私が代わりにBL

の... BX権利を使用することを学びたいはまた、私はかなりBXを理解していない理由ですに..を参照してください。私は絶対アドレスにジャンプするためにBXを使用する場合、実際のアドレスを1つ増やす必要がありますか?ThumbコードからThumbコードをキャッシングすると(lsbバイト1を維持するために)... CPUがサムコードを認識しますか?

答えて

3

BIG編集:私はそのアドレスにBLを生成するようにリンカーに指示する方法を知らない私が最近学んだことに基づいて回答や質問

まずオフのより良い理解を変更

ハードコードされたアドレスであり、実際にはこのコードには含まれません。あなたは、ラベルやそのようなダミーかコードなしのelfファイルを作成しようとするかもしれませんが、それがリンカーをだますかどうかはわかりません。リンカスクリプトも同様に変更する必要があります。それだけの価値はありません。

この1から生み出された、あなたの他の質問:これを分岐する

Arm/Thumb: using BX in Thumb code, to call a Thumb function, or to jump to a Thumb instruction in another function

だけで正常に動作します:

LDR R6, =0x24000 
ADD R6, #1  @ (set lsb to 1) 
BX R6 

または命令を保存して、ちょうどこの

LDR R6, =0x24001 
BX R6 
を行います

リンクをブランチしたい場合は、アドレスを知っているあなたは、アームモードで起動し、あなたが既に知っているアドレスに親指コードを取得したい場合、あなたはその後、

ldr r6,=0x24001 
    bl thumb_trampoline 
    ;@returns here 
    ... 
.thumb_func 
thumb_trampoline: 
    bx r6 

、ほぼ正確に同じ親指モードになっているとThumbコードを取得したいです。

ldr r6,=0x24001 
    bl arm_trampoline 
    ;@returns here 
    ... 
arm_trampoline: 
    bx r6 

は、あなたがこのような方法でR6をゴミ箱(このコードと呼ばれるいくつかのコードで使用されているいくつかの値を保存してくださいR6イマイチを作る)ことができることを知っている必要があります。

非常に申し訳ありませんが、他の答えであなたを誤解している、私はmov lr、PCはモードとしてlsbitに引っ張って誓うことができますが、それdoesnt。

+0

は相対的絶対的なものではなく、あなただけのプログラムカウンタの相対アドレスに分岐することができます。これは固定語長の命令セットで、モード切替えが可能ですが、レジスタに限定されているbxを使用するか、上に示したように、または可能であればモードに基づいて使用します(アームモードでのみ動作します)ldr pc 、= function_nameは長い枝であり、別の単語(可変長語命令のような)を使用しますが、bxのように分岐リンクではありません。 –

+0

ありがとう、良い説明のために。しかし、私はファームウェアの既存の親指機能をBLにすることができたいと思っています。そのために私はアドレスを知っています。この方法では、私はLRを混乱させる必要はありませんが、アセンブラやリンカスクリプトにこれを入れる方法がわかりません...もし私がBL LABELをしたら、アセンブラにLABELそれは私のコードではないからです...そして、それを教える方法がわからないから – vmanta

+0

私は答えを受け入れます、それは良い情報です...誰でも知っていればまだ.. pls reply。方法があるはずです。リンカーはどのようにインポートする関数(コードが呼び出す外部関数)にリンクするのですか?asmやリンカーのスクリプトでは、その指示にどのような指令を使用しますか? – vmanta

0

受け入れられた答えは目的を達成しますが、質問に答えて正確に対処するには、.equディレクティブを使用して定数valeをシンボルに関連付けることができます。この定数は、命令のオペランドとして使用できます。これは、必要なときに/場合、アセンブラはトランポリンを合成あります

次のアセンブリを生成
equ myFirmwareFunction, 0x12346570 
.globl _start 
     mov r0, #42 
     b myFirmwareFunction 

[1]

01000000 <_start>: 
1000000: e3a0002a mov r0, #42 ; 0x2a 
1000004: eaffffff b 1000008 <__*ABS*0x12346570_veneer> 

01000008 <__*ABS*0x12346570_veneer>: 
__*ABS*0x12346570_veneer(): 
1000008: e51ff004 ldr pc, [pc, #-4] ; 100000c <__*ABS*0x12346570_veneer+0x4> 
100000c: 12346570 data: #0x12345670 

を即値オフセットPCに十分に近い場合に適合します即時フィールドの場合、バーナ(トランポリン)はスキップされ、指定された定数アドレスへの単一の分岐命令が得られます。

[1]でcodesorcery(2009Q1)ツールチェーンを使用して:あなたは命令BLのエンコードを見れば 今arm-none-eabi-gcc -march=armv7-a -x assembler test.spp -o test.elf -Ttext=0x1000000 -nostdlib

関連する問題