目次
前
次
HEXフォーマットファイル表示(Python)
HEXフォーマットは、ROMライターに渡す
プログラム情報を格納する形式として有名。
アセンブラ、コンパイラが生成したHEXフォーマット
ファイルの内容の中で、ROMに書き込まれるバイト列
を確認するため、Pythonスクリプトを作成。
ターゲットのHEXフォーマットファイルの内容は、以下。
:080000000001020304050607DC
:0800080008090A0B0C0D0E0F94
:080010000102030405060708C4
:08001800090A0B0C0D0E0F107C
:080020000203040506070809AC
:080028000A0B0C0D0E0F101164
:08003000030405060708090A94
:080038000B0C0D0E0F1011124C
:080040000405060708090A0B7C
:080048000C0D0E0F1011121334
:0800500005060708090A0B0C64
:080058000D0E0F10111213141C
:08006000060708090A0B0C0D4C
:080068000E0F10111213141504
:080070000708090A0B0C0D0E34
:080078000F10111213141516EC
:0800800008090A0B0C0D0E0F1C
:080088001011121314151617D4
:08009000090A0B0C0D0E0F1004
:080098001112131415161718BC
:0800a0000A0B0C0D0E0F1011EC
:0800a8001213141516171819A4
:0800b0000B0C0D0E0F101112D4
:0800b800131415161718191A8C
:0800c0000C0D0E0F10111213BC
:0800c8001415161718191A1B74
:0800d0000D0E0F1011121314A4
:0800d80015161718191A1B1C5C
:0800e0000E0F1011121314158C
:0800e800161718191A1B1C1D44
:0800f0000F1011121314151674
:0800f8001718191A1B1C1D1E2C
:00000001FF
HEXフォーマットの1行の並びは、次の項目を
含みます。
- :(HEXフォーマットであることを示すヘッダ)
- バイト数(16進数2桁)
- アドレス(16進数4桁)
- レコードタイプ(16進数2桁)
- データバイト列
- チェックサム
これらの内容を踏まえて、スクリプトを一歩一歩ずつ
作っていきます。
1行ごとの解析をしたいので、ファイルをオープンしてから
リストの要素として、各行を読み込んでしまいます。
contextlist = fd.readlines()
リストcontextlistに入っている要素数を求めて
最終行を除いて、解析ができるように繰り返し
に持ち込み。
# calculate line number
last = len( contextlist )
for i in range(last-1) :
変数iには、リストの要素の番号が入ってくるので
対象となる行を取り出し。
16進数が含まれるので、大文字で扱いやすくして
おきます。
# get 1 line
es = contextlist[i].upper()
取り出した1行の中には、改行文字が
含まれているので、取り除き。
# delete new line
e = es[:-1]
データサイズ、アドレス、バイト列を取り出し。
# data size
dsize = int( e[1:3] , 16 )
# address
adr = e[3:7]
# data
ddat = e[9:len(e)-2]
最終的には、次のように1行に表示したいので
文字列として合体させていきます。
:080000000001020304050607DC => 0x0000 : 00 01 02 03 04 05 06 07
ソースの1行とアドレスまでを文字列
として合体。
# concatenate
tmp = e + ' => '
tmp += '0x'+ adr + ' : '
バイト列は、2桁を表示したら、スペースを入れて
見やすくしておくため、文字列にまとめます。
# separate context
ee = ''
for e in range(dsize) :
ii = 2 * e
ee += ddat[ii:ii+2] + ' '
tmp += ee
ファイルのオープン、クローズを含めて
手続きにします。
def showfilecontext(fn) :
# open
fd = open( fn , 'r' )
# get lines in list format
contextlist = fd.readlines()
# calculate line number
last = len( contextlist )
for i in range(last-1) :
# get 1 line
es = contextlist[i].upper()
# delete new line
e = es[:-1]
# data size
dsize = int( e[1:3] , 16 )
# address
adr = e[3:7]
# data
ddat = e[9:len(e)-2]
# concatenate
tmp = e + ' => '
tmp += '0x'+ adr + ' : '
# separate context
ee = ''
for e in range(dsize) :
ii = 2 * e
ee += ddat[ii:ii+2] + ' '
tmp += ee
print( tmp )
# close
fd.close()
コマンドラインから、ファイル名を与えて
処理することにして、メイン部分を定義。
# main handling
if __name__ == '__main__':
# get command line arguments
args = sys.argv
# judge
if len( args ) < 2 :
print( 'Error => no file name' )
exit(0)
# get file name
fname = args[1]
# show
showfilecontext( fname )
コマンドラインでの処理には、ライブラリを
使えばよいので、sysを使い文字コードの指定
を入れると、スクリプトは以下。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
def showfilecontext(fn) :
# open
fd = open( fn , 'r' )
# get lines in list format
contextlist = fd.readlines()
# calculate line number
last = len( contextlist )
for i in range(last-1) :
# get 1 line
es = contextlist[i].upper()
# delete new line
e = es[:-1]
# data size
dsize = int( e[1:3] , 16 )
# address
adr = e[3:7]
# data
ddat = e[9:len(e)-2]
# concatenate
tmp = e + ' => '
tmp += '0x'+ adr + ' : '
# separate context
ee = ''
for e in range(dsize) :
ii = 2 * e
ee += ddat[ii:ii+2] + ' '
tmp += ee
print( tmp )
# close
fd.close()
# main handling
if __name__ == '__main__':
# get command line arguments
args = sys.argv
# judge
if len( args ) < 2 :
print( 'Error => no file name' )
exit(0)
# get file name
fname = args[1]
# show
showfilecontext( fname )
使い方は、次のようにタイプ。
python showhex.py tst.hex{enter}
I/Oリダイレクトで、ファイルに落として
みると、次のようになります。
:080000000001020304050607DC => 0x0000 : 00 01 02 03 04 05 06 07
:0800080008090A0B0C0D0E0F94 => 0x0008 : 08 09 0A 0B 0C 0D 0E 0F
:080010000102030405060708C4 => 0x0010 : 01 02 03 04 05 06 07 08
:08001800090A0B0C0D0E0F107C => 0x0018 : 09 0A 0B 0C 0D 0E 0F 10
:080020000203040506070809AC => 0x0020 : 02 03 04 05 06 07 08 09
:080028000A0B0C0D0E0F101164 => 0x0028 : 0A 0B 0C 0D 0E 0F 10 11
:08003000030405060708090A94 => 0x0030 : 03 04 05 06 07 08 09 0A
:080038000B0C0D0E0F1011124C => 0x0038 : 0B 0C 0D 0E 0F 10 11 12
:080040000405060708090A0B7C => 0x0040 : 04 05 06 07 08 09 0A 0B
:080048000C0D0E0F1011121334 => 0x0048 : 0C 0D 0E 0F 10 11 12 13
:0800500005060708090A0B0C64 => 0x0050 : 05 06 07 08 09 0A 0B 0C
:080058000D0E0F10111213141C => 0x0058 : 0D 0E 0F 10 11 12 13 14
:08006000060708090A0B0C0D4C => 0x0060 : 06 07 08 09 0A 0B 0C 0D
:080068000E0F10111213141504 => 0x0068 : 0E 0F 10 11 12 13 14 15
:080070000708090A0B0C0D0E34 => 0x0070 : 07 08 09 0A 0B 0C 0D 0E
:080078000F10111213141516EC => 0x0078 : 0F 10 11 12 13 14 15 16
:0800800008090A0B0C0D0E0F1C => 0x0080 : 08 09 0A 0B 0C 0D 0E 0F
:080088001011121314151617D4 => 0x0088 : 10 11 12 13 14 15 16 17
:08009000090A0B0C0D0E0F1004 => 0x0090 : 09 0A 0B 0C 0D 0E 0F 10
:080098001112131415161718BC => 0x0098 : 11 12 13 14 15 16 17 18
:0800A0000A0B0C0D0E0F1011EC => 0x00A0 : 0A 0B 0C 0D 0E 0F 10 11
:0800A8001213141516171819A4 => 0x00A8 : 12 13 14 15 16 17 18 19
:0800B0000B0C0D0E0F101112D4 => 0x00B0 : 0B 0C 0D 0E 0F 10 11 12
:0800B800131415161718191A8C => 0x00B8 : 13 14 15 16 17 18 19 1A
:0800C0000C0D0E0F10111213BC => 0x00C0 : 0C 0D 0E 0F 10 11 12 13
:0800C8001415161718191A1B74 => 0x00C8 : 14 15 16 17 18 19 1A 1B
:0800D0000D0E0F1011121314A4 => 0x00D0 : 0D 0E 0F 10 11 12 13 14
:0800D80015161718191A1B1C5C => 0x00D8 : 15 16 17 18 19 1A 1B 1C
:0800E0000E0F1011121314158C => 0x00E0 : 0E 0F 10 11 12 13 14 15
:0800E800161718191A1B1C1D44 => 0x00E8 : 16 17 18 19 1A 1B 1C 1D
:0800F0000F1011121314151674 => 0x00F0 : 0F 10 11 12 13 14 15 16
:0800F8001718191A1B1C1D1E2C => 0x00F8 : 17 18 19 1A 1B 1C 1D 1E
目次
前
次