ビット表示スクリプト

組み込み系の仕事をしているとビット操作がどうしても多くなってくる。
けどアセンブラやCとかでいじる場合には値を直で設定してやることも多い。


こんなかんじで。

volatile char *hoge = 0x1234;

*hoge = 0xabcd;


けどハードウェア仕様書は各ビット毎に0,1が書いてあるだけ。
これって分かりづらいので簡単なビットを見やすくする簡単なスクリプトを書いてみた。

#!/usr/bin/env ruby

#このArray部分はネットで見つけて使っているもの
#どこのサイトで頂いたかは失念。
class Array
  def sandwich(sep)
    sep + join(sep) + sep
  end

  #asciiのテーブルを作成する
  #print CSV::Reader.parse(File.read("hoge.csv")).to_a.to_ascii_table
  def to_ascii_table
    col_length = self.transpose.map{|cols| cols.map{|col| col.to_s.length}.max}

    rule = col_length.map{|len| '-'*len}.sandwich('+')+"\n"

    self.map{|row|
      row.zip(col_length).map{|col,len| col.ljust(len)}.sandwich('|')+"\n"
    }.sandwich(rule)
  end
end


#引数のチェック用
#邪魔なので分けてあるだけ
def check(val)
  if val == 0
    puts "Error!! zero or strings."
    exit
  end

  if val.to_s(2).size > 32
    puts "Error!! value's length is over 32bit."
    exit
  end
end


while val = ARGV.shift
  val = val.to_i(0)
  check(val)

  printf("0x%s\n", val.to_s(16))
  printf("0b%s\n", val.to_s(2))

  ary = []
  tmp = ["bit"]
  tmp += Array.new(32){|i|("0"*2+i.to_s)[-2..-1]}.reverse
  ary << tmp

  tmp = ["value"]
  str = "0"*32+val.to_s(2)
  tmp += str.split(//)[-32..-1]
  ary << tmp

  puts ary.to_ascii_table+"\n"
end


出力はこんな感じ。
2、10、16進数等普通に解釈してくれる。

$ rbitview.rb 0x123
0x123
0b100100011
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|bit  |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|value|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |1 |1 |
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

$ rbitview.rb 123
0x7b
0b1111011
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|bit  |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|value|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |1 |1 |1 |1 |0 |1 |1 |
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

$ rbitview.rb 0b110011
0x33
0b110011
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|bit  |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|value|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |1 |1 |0 |0 |1 |1 |
+-----+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+


追記
aa記法にしたけどすこし見づらい。