目次

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行の並びは、次の項目を
 含みます。

 これらの内容を踏まえて、スクリプトを一歩一歩ずつ
 作っていきます。

 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 


目次

inserted by FC2 system