MPLABで開発を行い、コンパイル(orアセンブル)を行うと*.hexファイルが作成されます。
PICのマイコンへは、hexファイルを元に書き込みが行われます。
このhexですが、エディタで開いてみると普通のテキストファイルである事が分かります。
前回の動作確認で作ったasmファイルを確認してみると、以下の様な内容になりました。
作成したPICのアセンブラコード
; LEDを点滅させる ; (点滅が速過ぎるので、実機で実行すると目視では確認できませんが...) LIST P=16F84 INCLUDE P16F84A.INC ORG 0 ; ポートBのRB0ピンを出力にする BSF STATUS, RP0 CLRF TRISA CLRF TRISB MOVLW B'00000001' MOVWF PORTB BCF STATUS, RP0 LOOP ; ポートBを全ビットOFFにする MOVLW B'00000000' MOVWF H'05' ; ポートBの再下位ビットをONにする MOVLW B'00000001' MOVWF H'05' goto LOOP END |
作成されたhexファイル
:020000040000FA :100000008316850186010130860083120030850049 :0600100001308500062806 :04001600003400347E :00000001FF |
MPLABで見たプログラム領域の16進ダンプ(メニューバーよりView->Program Memory)
ダンプを命令単位で逆アセンブルした結果
hexファイルの中身ですがMPLABの独自フォーマットというわけではなく、インテルHEXフォーマットという良く使われる汎用の書式になっており、フラッシュメモリ上のどの位置に何のデータを書くべきかが指定されています。
フォーマットはかなりシンプルで、以下の仕様になっています。
Intel hex format仕様
ファイルはテキスト形式で、16進文字列で書き込むべきデータと、メモリ上のどこに書き込むかの絶対アドレスが記述されています。ファイルは改行を区切り文字とした、複数のレコードで構成されています。
レコードフォーマット
各レコードは可変長の構成をとり、以下の6つのフィールドで構成されるレコードフォーマットとなっています。フィールド名 データ長(byte) ----------------------- -------------- スタートコード 1 データ長 2 アドレスオフセット値 4 レコード種別 2 データ 可変長 チェックサム 2 |
各フィールドの意味
各フィールドの意味は以下の通りです。スタートコード
固定で”:”が入ります。データ長
2桁の16進文字列で、5番目のフィールドであるデータ部の長さを指定します。例えば”10″だった場合は、データ部が16byteである事と意味します。
データは16進文字列で表記されており1文字が4bit分の情報を持つので、データ長が”10″だった時は、エディタで見ると32文字書かれている形になります。
アドレスオフセット値
ROMやフラッシュメモリに書き込む際の開始アドレスです。16進で4桁ということは16bitなので、ここでは最大64キロバイトまでのオフセットを指定可能です。
この項目は、必ずビッグエンディアンで記載されるので、値が”0100″だった時、オフセットは10進表記で”256″となります。
レコード種別
2桁で”00″~”05″の値が指定されます。各値の意味は後述します。
データ
実際に書き込むべきデータです。バイトオーダーは、実際に書き込むべきROMに依存します。
(リトルエンディアンのときもあれば、ビッグエンディアンの場合もあります)
ちなみに、MPLABではリトルエンディアンなので、エディタで確認すると順序が逆になっているように見えます。
(詳細はこちらも後で確認します)
チェックサム
前述したフィールドのうち、”データ長、アドレスオフセット値、レコード種別、データ”部の各バイトを合計した後、2の補数をとった値です。合計値が0xFFを超える場合は、下位2byteのみを採用します。
例として、対象のデータが”020000002030″だった場合、02 + 00+ 00 + 00 + 20 + 30 = “52”となり、2の補数を取ると”AD”になります。
レコード種別
レコード種別のフィールドには”00″~”05″が入り、それぞれ以下の意味を持っています。00
データフィールドです。01
ファイルの最後を意味します。最後のレコードは必ずレコード種別が01になります。
このレコードは、データ長が”00″で、データフィールドはブランクになります
02
拡張セグメントアドレスを意味するレコードです。データフィールドにはセグメントのアドレスが、ビッグエンディアンで入ります。
値をセットする場所が16bitの範囲を超える場合にこのレコードを使用し、以降のデータは”ここで指定されたアドレスを16倍した値”+”00レコードで指定されたアドレスオフセット値”の場所をオフセット値とみなします。
ファイル中にこのレコードがない場合は、セグメントは0x0000であるとみなします。
03
開始セグメントアドレスを意味します。80×86プロセッサ用の命令で、プログラムをどこから実行するかを指定します。
PICマイコンには関係有りません。
04
拡張リニアアドレスを意味します。32ビットアドレス空間をフルにアクセスするために作成されたレコードです。
このレコードでは、アドレス指定のうち上位16ビット分を指定します。
以降のデータは、”ここで指定されたアドレスを16ビット左シフトした値”+”00レコードで指定されたアドレスオフセット値”をオフセット値とみなします。
PICマイコンでは、32bitもアドレス空間が無いので関係有りません。
(出力ファイルを見ると0x0000が指定されているようです)
05
開始リニアアドレスを意味します。レコード種別=”03″のデータに対して、プログラムの開始位置を32ビットアドレス空間をフルにアクセスするために作成されたレコードです。
こちらもPICマイコンには関係有りません。
MPLABで作成されたhexファイルを確認してみる
先ほど提示したhexファイル(MPLABにて作成されたモノ)を再掲します。
このファイルを、説明したファイルフォーマットにしたがって解析していきます。
:020000040000FA :100000008316850186010130860083120030850049 :0600100001308500062806 :04001600003400347E :00000001FF |
このままだと分かり辛いので、各フィールドをスペースで区切っています。
データフィールドは可変長ですが、PICの命令は16bit単位で1命令記載されているので、4文字単位で区切ってみます。
: 02 0000 04 0000 FA : 10 0000 00 8316 8501 8601 0130 8600 8312 0030 8500 49 : 06 0010 00 0130 8500 0628 06 : 04 0016 00 0034 0034 7E : 00 0000 01 FF |
1行目はオフセット指定で、データは”0000″なので気にしなくてよいです。
2行目からが命令が入っている部分になります。
レコード長が”10″なので、データ長は”8316 8501 8601 0130 8600 8312 0030 8500″の16byteになります。最初のデータに注目すると”8316″となっていますが、PICはリトルエンディアンなので、機械語は”1683″となります。
MPLABで確認すると、最初の命令は確かに”1683″になっています。
以降のデータも同様に確認していくと、hexファイルのデータを読み解く事が出来るかと思います。
参考文献:
http://en.wikipedia.org/wiki/Intel_HEX
http://www.interlog.com/~speff/usefulinfo/Hexfrmt.pdf
Binary Hacks ―ハッカー秘伝のテクニック100選
関連記事
[…] (下記参考にしました. http://nanoappli.com/blog/archives/3307 http://quickturn.xrea.jp/pic/hexfile.html ) […]