awkで書いたSPARC V8逆アセンブラ

説明

nawkで記述したSPARC V8の逆アセンブラです。gawkでも動作します。最初の行の#! /usr/bin/nawk -f を/usr/bin/awk -f や/usr/bin/gawk -f に書き換えてください。(きょうびawkとnawkの区別はなく、awkでいいみたい)

[戻る]

実行例

実行後に16進でアドレス8桁+スペース+データ8桁を入力すると、ニーモニックを表示します。これらの列をテキストファイルにして標準入力に入れたらすべて変換します。
mbp13:~ takesita$ chmod +x craps.awk
mbp13:~ takesita$ ./craps.awk
00000000 01000000
00000000 : 01000000  nop     
^D
mbp13:~ takesita$
[戻る]

ソースコード


#! /usr/bin/nawk -f
#
# craps.awk  - sparc disassembler 
#
# 95/04/07	ver 1.0   by Katsunori Takeshita
# 95/04/10	ver 1.1   alu implement
# 95/05/24	ver 1.2   rd operand decode miss
#

BEGIN {
	H2B["0"]="0000" ;
	H2B["1"]="0001" ;
	H2B["2"]="0010" ;
	H2B["3"]="0011" ;
	H2B["4"]="0100" ;
	H2B["5"]="0101" ;
	H2B["6"]="0110" ;
	H2B["7"]="0111" ;
	H2B["8"]="1000" ;
	H2B["9"]="1001" ;
	H2B["A"]="1010" ;
	H2B["B"]="1011" ;
	H2B["C"]="1100" ;
	H2B["D"]="1101" ;
	H2B["E"]="1110" ;
	H2B["F"]="1111" ;
	H2B["a"]="1010" ;
	H2B["b"]="1011" ;
	H2B["c"]="1100" ;
	H2B["d"]="1101" ;
	H2B["e"]="1110" ;
	H2B["f"]="1111" ;
#
	B2H["0000"]="0" ;
	B2H["0001"]="1" ;
	B2H["0010"]="2" ;
	B2H["0011"]="3" ;
	B2H["0100"]="4" ;
	B2H["0101"]="5" ;
	B2H["0110"]="6" ;
	B2H["0111"]="7" ;
	B2H["1000"]="8" ;
	B2H["1001"]="9" ;
	B2H["1010"]="A" ;
	B2H["1011"]="B" ;
	B2H["1100"]="C" ;
	B2H["1101"]="D" ;
	B2H["1110"]="E" ;
	B2H["1111"]="F" ;
#
	REG["00000"]="%g0" ;
	REG["00001"]="%g1" ;
	REG["00010"]="%g2" ;
	REG["00011"]="%g3" ;
	REG["00100"]="%g4" ;
	REG["00101"]="%g5" ;
	REG["00110"]="%g6" ;
	REG["00111"]="%g7" ;
	REG["01000"]="%o0" ;
	REG["01001"]="%o1" ;
	REG["01010"]="%o2" ;
	REG["01011"]="%o3" ;
	REG["01100"]="%o4" ;
	REG["01101"]="%o5" ;
	REG["01110"]="%o6" ;
	REG["01111"]="%o7" ;
	REG["10000"]="%l0" ;
	REG["10001"]="%l1" ;
	REG["10010"]="%l2" ;
	REG["10011"]="%l3" ;
	REG["10100"]="%l4" ;
	REG["10101"]="%l5" ;
	REG["10110"]="%l6" ;
	REG["10111"]="%l7" ;
	REG["11000"]="%i0" ;
	REG["11001"]="%i1" ;
	REG["11010"]="%i2" ;
	REG["11011"]="%i3" ;
	REG["11100"]="%i4" ;
	REG["11101"]="%i5" ;
	REG["11110"]="%i6" ;
	REG["11111"]="%i7" ;
#
	Bicc["0000"]="bn" ;
	Bicc["0001"]="be" ;
	Bicc["0010"]="ble" ;
	Bicc["0011"]="bl" ;
	Bicc["0100"]="bleu" ;
	Bicc["0101"]="bcs" ;
	Bicc["0110"]="bneg" ;
	Bicc["0111"]="bvs" ;
	Bicc["1000"]="ba" ;
	Bicc["1001"]="bne" ;
	Bicc["1010"]="bg" ;
	Bicc["1011"]="bge" ;
	Bicc["1100"]="bgu" ;
	Bicc["1101"]="bcc" ;
	Bicc["1110"]="bpos" ;
	Bicc["1111"]="bvc" ;
#
	CBccc["0000"]="cbn" ;
	CBccc["0001"]="cb123" ;
	CBccc["0010"]="cb12" ;
	CBccc["0011"]="cb13" ;
	CBccc["0100"]="cb1" ;
	CBccc["0101"]="cb23" ;
	CBccc["0110"]="cb2" ;
	CBccc["0111"]="cb3" ;
	CBccc["1000"]="cba" ;
	CBccc["1001"]="cb0" ;
	CBccc["1010"]="cb03" ;
	CBccc["1011"]="cb02" ;
	CBccc["1100"]="cb023" ;
	CBccc["1101"]="cb01" ;
	CBccc["1110"]="cb013" ;
	CBccc["1111"]="cb012" ;
#
	FBfcc["0000"]="fbn" ;
	FBfcc["0001"]="fbne" ;
	FBfcc["0010"]="fblg" ;
	FBfcc["0011"]="fbul" ;
	FBfcc["0100"]="fbl" ;
	FBfcc["0101"]="fbug" ;
	FBfcc["0110"]="fbg" ;
	FBfcc["0111"]="fbu" ;
	FBfcc["1000"]="fba" ;
	FBfcc["1001"]="fbe" ;
	FBfcc["1010"]="fbue" ;
	FBfcc["1011"]="fbge" ;
	FBfcc["1100"]="fbuge" ;
	FBfcc["1101"]="fble" ;
	FBfcc["1110"]="fbule" ;
	FBfcc["1111"]="fbo" ;
#
	Ticc["0000"]="tn" ;
	Ticc["0001"]="te" ;
	Ticc["0010"]="tle" ;
	Ticc["0011"]="tl" ;
	Ticc["0100"]="tleu" ;
	Ticc["0101"]="tcs" ;
	Ticc["0110"]="tneg" ;
	Ticc["0111"]="tvs" ;
	Ticc["1000"]="ta" ;
	Ticc["1001"]="tne" ;
	Ticc["1010"]="tg" ;
	Ticc["1011"]="tge" ;
	Ticc["1100"]="tgu" ;
	Ticc["1101"]="tcc" ;
	Ticc["1110"]="tpos" ;
	Ticc["1111"]="tvc" ;
#
	ALU01["0000"]="add" ;
	ALU01["0001"]="and" ;
	ALU01["0010"]="or" ;
	ALU01["0011"]="xor" ;
	ALU01["0100"]="sub" ;
	ALU01["0101"]="andn" ;
	ALU01["0110"]="orn" ;
	ALU01["0111"]="xnor" ;
	ALU01["1000"]="addx" ;
	ALU01["1001"]="XXX" ;
	ALU01["1010"]="umul" ;
	ALU01["1011"]="smul" ;
	ALU01["1100"]="subx" ;
	ALU01["1101"]="XXX" ;
	ALU01["1110"]="udiv" ;
	ALU01["1111"]="sdiv" ;
#
	ALU2["0000"]="taddcc" ;
	ALU2["0001"]="tsubcc" ;
	ALU2["0010"]="taddcctv" ;
	ALU2["0011"]="tsubcctv" ;
	ALU2["0100"]="mulscc" ;
	ALU2["0101"]="sll" ;
	ALU2["0110"]="srl" ;
	ALU2["0111"]="sra" ;
	ALU2["1000"]="rd" ;	# stbar,rdasr,rdy
	ALU2["1001"]="rd" ;	# rdpsr
	ALU2["1010"]="rd" ;	# rdwim
	ALU2["1011"]="rd" ;	# rdtbr
	ALU2["1100"]="XXX" ;
	ALU2["1101"]="XXX" ;
	ALU2["1110"]="XXX" ;
	ALU2["1111"]="XXX" ;
#
	ALU3["0000"]="wr" ;	# wrasr,wry
	ALU3["0001"]="wr" ;	# wrpsr
	ALU3["0010"]="wr" ;	# wrwim
	ALU3["0011"]="wr" ;	# wrtbr
	ALU3["0100"]="FPop1" ;
	ALU3["0101"]="FPop2" ;
	ALU3["0110"]="CPop1" ;
	ALU3["0111"]="CPop2" ;
	ALU3["1000"]="jmpl" ;
	ALU3["1001"]="rett" ;
	ALU3["1010"]="ticc" ; # Ticc
	ALU3["1011"]="flush" ;
	ALU3["1100"]="save" ;
	ALU3["1101"]="restore" ;
	ALU3["1110"]="XXX" ;
	ALU3["1111"]="XXX" ;
#
	LD01["0000"]="ld" ;
	LD01["0001"]="ldub" ;
	LD01["0010"]="lduh" ;
	LD01["0011"]="ldd" ;
	LD01["0100"]="st" ;
	LD01["0101"]="stb" ;
	LD01["0110"]="sth" ;
	LD01["0111"]="std" ;
	LD01["1000"]="XXX" ;
	LD01["1001"]="ldsb" ;
	LD01["1010"]="ldsh" ;
	LD01["1011"]="XXX" ;
	LD01["1100"]="XXX" ;
	LD01["1101"]="ldstub" ;
	LD01["1110"]="XXX" ;
	LD01["1111"]="swap" ;
#
	LD2["0000"]="ldf" ;
	LD2["0001"]="ldfsr" ;
	LD2["0010"]="XXX" ;
	LD2["0011"]="lddf" ;
	LD2["0100"]="stf" ;
	LD2["0101"]="stfsr" ;
	LD2["0110"]="stdfq" ;
	LD2["0111"]="stdf" ;
	LD2["1000"]="XXX" ;
	LD2["1001"]="XXX" ;
	LD2["1010"]="XXX" ;
	LD2["1011"]="XXX" ;
	LD2["1100"]="XXX" ;
	LD2["1101"]="XXX" ;
	LD2["1110"]="XXX" ;
	LD2["1111"]="XXX" ;
#
	LD3["0000"]="ldc" ;
	LD3["0001"]="ldcsr" ;
	LD3["0010"]="XXX" ;
	LD3["0011"]="lddc" ;
	LD3["0100"]="stc" ;
	LD3["0101"]="stcsr" ;
	LD3["0110"]="stdcq" ;
	LD3["0111"]="stdc" ;
	LD3["1000"]="XXX" ;
	LD3["1001"]="XXX" ;
	LD3["1010"]="XXX" ;
	LD3["1011"]="XXX" ;
	LD3["1100"]="XXX" ;
	LD3["1101"]="XXX" ;
	LD3["1110"]="XXX" ;
	LD3["1111"]="XXX" ;
#
	ASR["00000"]="%y" ;
	ASR["00001"]="%asr_1" ;
	ASR["00010"]="%asr_2" ;
	ASR["00011"]="%asr_3" ;
	ASR["00100"]="%asr_4" ;
	ASR["00101"]="%asr_5" ;
	ASR["00110"]="%asr_6" ;
	ASR["00111"]="%asr_7" ;
	ASR["01000"]="%asr_8" ;
	ASR["01001"]="%asr_9" ;
	ASR["01010"]="%asr_10" ;
	ASR["01011"]="%asr_11" ;
	ASR["01100"]="%asr_12" ;
	ASR["01101"]="%asr_13" ;
	ASR["01110"]="%asr_14" ;
	ASR["01111"]="%asr_15" ;
}

{
	ADDR = $1 ;
	DATA = $2 ; INST = h2b( $2 );
	OPCODE = "" ; OPRAND = "" ;

#	1st decode
	op = substr( INST,1,2 ) ;

	if ( op=="01" ) {		# call
		dist = substr(INST,3) "00" ;
		OPCODE = "call" ;
		OPRAND = "0x" b2h(dist);
		writeln( ADDR,DATA,OPCODE,OPRAND );
		next ;
	}

	if ( op=="00" ) {		# F2 - branch,sethi,nop
		# 2nd decode
		op2 = substr(INST,8,3) ;
		if ( op2=="000" ) {	# unimplement
			OPCODE = "unimp" ;
			OPRAND = DATA ;
		}
		if ( op2=="100" ) {	# sethi | nop
			rd = substr(INST,3,5);
			disp22 = substr(INST,11);
			if ( rd+0 + disp22+0 == 0 ) {
				OPCODE = "nop" ;
			} else {
				OPCODE = "sethi" ;
				rd = REG[rd];
				t = disp22 "0000000000" ;
				OPRAND = "%hi(0x" b2h(t) ")," rd;
			}
		}
		if ( op2=="010" || op2=="110" ||op2=="111" ) {	# branch
			cond = substr(INST,4,4) ;
			if ( op2=="010" ) OPCODE = Bicc[cond] ;
			if ( op2=="110" ) OPCODE = FBfcc[cond] ;
			if ( op2=="111" ) OPCODE = CBccc[cond] ;
			a = substr(INST,3,1);
			if ( a=="1" ) OPCODE = OPCODE ",a" ;
			disp22 = substr(INST,11,22) ;
			OPRAND = "+" getsimm22(disp22) ;
		}
		writeln( ADDR,DATA,OPCODE,OPRAND );
		next ;
	}

	if ( op=="10" ) {		# F3 - ALU
		op3_30 = substr(INST,10,4) ;
		op3_54 = substr(INST,8,2) ;
		rd = REG[substr(INST,3,5)] ;
		rs1 = REG[substr(INST,14,5)] ;
		if ( substr(INST,19,1) == "1" ) {
			rs2 = substr(INST,20,13) ;
			rs2 = "0x" b2h( rs2 ) ;
		} else {
			rs2 = REG[substr(INST,28,5)] ;
		}

		if ( op3_54 == "00" || op3_54=="01" ) {
			OPCODE = ALU01[op3_30] ;
			if ( op3_54=="01" ) OPCODE = OPCODE "cc" ;
			OPRAND = rs1 "," rs2 "," rd ;
		}
		if ( op3_54 == "10" ) {
			OPCODE = ALU2[op3_30] ;
			if ( OPCODE == "rd" ) {
				if ( op3_30=="1001" ) rs1 = "%psr" ;
				if ( op3_30=="1010" ) rs1 = "%wim" ;
				if ( op3_30=="1011" ) rs1 = "%tbr" ;
				if ( op3_30=="1000" ) {
					if ( rd=="%g0" && rs1=="%o7" ) {
						OPCODE = "stbar" ;
						OPRAND = "" ;
					}
					rs1 = ASR[substr(INST,14,5)];
				}
				if ( OPCODE == "rd" ) {
					OPRAND = rs1 "," rd ;
				}
			} else {
				OPRAND = rs1 "," rs2 "," rd ;
			}
		}
		if ( op3_54 == "11" ) {
			OPCODE = ALU3[op3_30] ;
			if ( OPCODE == "wr" ) {
				if ( op3_30=="0001" ) rd = "%psr" ;
				if ( op3_30=="0010" ) rd = "%wim" ;
				if ( op3_30=="0011" ) rd = "%tbr" ;
				if ( op3_30=="0000" ) {
					rd = ASR[substr(INST,3,5)];
				}
				OPRAND = rs1 "," rs2 "," rd ;
			}
			if ( op3_30 == "1100" || op3_30 == "1101" ) {
				OPRAND = rs1 "," rs2 "," rd ;
			}
			if ( op3_30 == "1000" ) {	# jmpl
				OPRAND = getaddr(INST) "," rd ;
			}
			if ( op3_30 == "1001" || op3_30 == "1011" ) {
				OPRAND = getaddr(INST) ;
			}
			if ( op3_30 == "1010" ) {	#Ticc
				cond = substr(INST,4,4) ;
				OPCODE = Ticc[cond] ;
				OPRAND = geteaddr(INST) ;
			}
			# CP/FP
		}
		writeln( ADDR,DATA,OPCODE,OPRAND );
		next ;
	}

	if ( op=="11" ) {		# F3 - LD/ST
		op3_30 = substr(INST,10,4) ;
		op3_54 = substr(INST,8,2) ;
		rd = REG[substr(INST,3,5)] ;

		if ( op3_54=="00" || op3_54=="01" ) {
			OPCODE = LD01[op3_30] ;
			if ( op3_54=="01" ) {
				OPCODE = OPCODE "a" ;
				OPRAND = getaddrasi(INST) ;
			} else {
				OPRAND = getaddr(INST);
			}
		}
		if ( substr(OPCODE,1,2)=="st" ) {
			OPRAND = rd "," OPRAND ;
		} else {
			OPRAND = OPRAND "," rd ;
		}

		writeln( ADDR,DATA,OPCODE,OPRAND );
		next ;
	}
}
#
function writeln( ADDR,DATA,OPCODE,OPRAND ) {
		if ( OPCODE =="" ) {
			printf( "%8s : %8s\n",ADDR,DATA );
			return ;
		}
		if ( OPRAND != "" ) {
			printf( "%8s : %8s  %-8s\t%s\n",ADDR,DATA,OPCODE,OPRAND );
		} else {
			printf( "%8s : %8s  %-8s\n",ADDR,DATA,OPCODE );
		}
}
#
function h2b( indata ,ans,l,i) {
	ans = "" ;
	l = length(indata);
	for ( i=1 ; i<=l ; i++ ) {
		ans = ans H2B[substr(indata,i,1)] ;
	}
	return ans ;
}
#
function b2h( indata ,ans,len,i) {
	ans = "" ;
	len = length(indata);
	if ( len%4!=0 ) {
		indata = substr("0000",1,4-(len%4)) indata ;
	}
	len = length(indata)/4 ;
	for ( i=0; i<len; i++ ) {
		ans = ans B2H[ substr(indata,1+i*4,4) ] ;
	}
	return ans ;
}
#
function geteaddr( inst, ans,rs1,rs2) {
	rs1 = REG[substr(inst,14,5)] ;
	if ( substr(inst,19,1)=="1" ) {
		ans = rs1 "+" getsimm13(inst) ;
	} else {
		rs2 = REG[substr(inst,28,5)] ;
		ans = rs1 "+" rs2 ;
	}
	return ans ;
}
#
function getaddr( inst ,a) {
	a = "[" geteaddr(inst) "]" ;
	return a ;
}
#
function getaddrasi( inst, ans,rs1,rs2,asi) {
	rs1 = REG[substr(inst,14,5)] ;
	rs2 = REG[substr(inst,28,5)] ;
	asi = b2h(substr(inst,20,8)) ;
	ans = "[" rs1 "+" rs2 "]0x" asi ;
	return ans ;
}
#
function getsimm13( inst, simm13) {
	simm13 = substr(inst,20,13);
	if ( substr(simm13,1,1)=="1" ) {
		simm13 = "1111111111111111111" simm13 ;
	}
	simm13 = "0x" b2h(simm13) ;
	return simm13 ;
}
#
function getsimm22( simm22 ) {
	if ( substr(simm22,1,1)=="1" ) {
		simm22 = "11111111" simm22 "00" ;
	} else {
		simm22 = "00000000" simm22 "00" ;
	}
	simm22 = "0x" b2h(simm22) ;
	return simm22 ;
}

[戻る]
inserted by FC2 system