web-dev-qa-db-ja.com

「awk-Wdump」によって生成されるアセンブラのような出力のリファレンスはありますか?

コマンド awk -W dump ...は「アセンブラのような」コードのダンプを生成します(示されているように ここでは[リンク] 、またはmanを読み取ることによって)。 jzステートメントによって生成され、明らかにジャンプゼロ命令であるifなど、一部の命令はその意味を簡単に推測できます。しかし、他の人はそれほどではありません。驚いたことに、awkが定義する命令セットへの参照が見つかりません。これはそのような出力の有用性を深刻に制限します。

オンラインでそのような参照はありますか?

2
Allen

質問は、バイトコードインタープリターを使用するため、主にmawkに関するものであり、アセンブリのような出力でバイトコードを表示するためのコマンドラインオプションについて言及しています。 gawkへの最近の変更(2010) 類似のものが追加されましたが、ニーモニック(およびコマンドラインオプション)は異なります。 gawkを使用すると、デバッガーを使用して(異なる)リストを取得できます。

いいえ、ソースコード以外に参照は書かれていません(通常、バイトコード操作のニーモニックを説明するコメントはありません)。

listの場合は、 code.h を読むことができますが、 da.c ファイルを分解するプロセスが役立ちます。ただし、actionexecute.c で実行されますが、チュートリアルはありません。

出力をより理解しやすくするために、最近いくつかの変更が加えられました。たとえば、 ct_length.awk ファイルのmawk1.3.3は次のとおりです。

MAIN
000 omain
001 jmp         084
003 pushs       "%s"
005 pushi       $0
007 pushd       1
009 pushi       i
011 pushd       5
013 add
014 pushint     3
016 substr
018 pushint     2
020 printf
022 f_pusha     $0
024 pushi       $0
026 pushi       i
028 pushd       6
030 add
031 pushint     2
033 substr
035 f_assign
036 pop
037 pushi       $0
039 pushc       0xfc2810        /^[ \t]*\(/
041 match
043 jz          078
045 pushs       "%s"
047 pushi       $0
049 pushd       1
051 pushi       RLENGTH
053 pushint     3
055 substr
057 pushint     2
059 printf
061 f_pusha     $0
063 pushi       $0
065 pushi       RLENGTH
067 pushd       1
069 add
070 pushint     2
072 substr
074 f_assign
075 pop
076 jmp         084
078 pushs       "($0)"
080 pushint     1
082 printf
084 pusha       i
086 pushi       $0
088 pushs       "length"
090 index
092 assign
093 jnz         003
095 pushint     0
097 print
099 ol_gl

20161120スナップショットは、正規表現の有限状態マシンを示しています(終わり近く)。

MAIN
000 .   omain
001 .   jmp             084
003 .   pushs   "%s"
005 .   pushi   $0
007 .   pushd   1
009 .   pushi   i
011 .   pushd   5
013 .   add
014 .   pushint 3
016 .   substr
018 .   pushint 2
020 .   printf
022 .   f_pusha $0
024 .   pushi   $0
026 .   pushi   i
028 .   pushd   6
030 .   add
031 .   pushint 2
033 .   substr
035 .   f_assign
036 .   pop
037 .   pushi   $0
039 .   pushc   0xbb7998        /^[ \t]*\(/
041 .   match
043 .   jz              078
045 .   pushs   "%s"
047 .   pushi   $0
049 .   pushd   1
051 .   pushi   RLENGTH
053 .   pushint 3
055 .   substr
057 .   pushint 2
059 .   printf
061 .   f_pusha $0
063 .   pushi   $0
065 .   pushi   RLENGTH
067 .   pushd   1
069 .   add
070 .   pushint 2
072 .   substr
074 .   f_assign
075 .   pop
076 .   jmp             084
078 .   pushs   "($0)"
080 .   pushint 1
082 .   printf
084 .   pusha   i
086 .   pushi   $0
088 .   pushs   "length"
090 .   index
092 .   assign
093 .   jnz             003
095 .   pushint 0
097 .   print
099 .   ol_gl
# regex 0xbb7998
000 .   M_START 
001 .   M_2JA   4       
002 .   M_SAVE_POS      
003 .   M_CLASS [\011 ] 
004 .   M_2JC   -2      
005 .   M_STR   "("     
006 .   M_ACCEPT  

Gawk 4.xでは、デバッガーを起動することで類似の情報を取得できます。

gawk -D -f cf_length.awk

コマンドラインからdumpに指示します。結果は次のとおりです。

gawk> dump

[      :0x55977de761e0] Op_newfile          : [target_jmp = 0x55977de751d0] [target_endfile = 0x55977de751f0]
                                              [target_get_record = 0x55977de75230]
[      :0x55977de75210] Op_no_op            : 
[      :0x55977de75970] Op_after_beginfile  : 
[      :0x55977de75230] Op_get_record       : [target_newfile = 0x55977de761e0]

        # Rule

[    10:0x55977de77b50] Op_rule             : [in_rule = Rule] [source_file = ct_length.awk]
[    12:0x55977de75310] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    12:0x55977de752f0] Op_field_spec       : 
[    12:0x55977de75370] Op_Push_i           : "length" [MALLOC|STRING|STRCUR]
[    12:0x55977de752d0] Op_builtin          : index [arg_count = 2]
[    12:0x55977de75270] Op_Push_lhs         : i [do_reference = false]
[    12:0x55977de75290] Op_assign           : 
[      :0x55977de75650] Op_lint             : [lint_type = LINT_assign_in_cond]
[      :0x55977de75450] Op_jmp_false        : [target_jmp = 0x55977de75810]
[    14:0x55977de75350] Op_Push_i           : "%s" [MALLOC|STRING|STRCUR]
[    14:0x55977de75410] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    14:0x55977de753f0] Op_field_spec       : 
[    14:0x55977de75470] Op_Push_i           : 1 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    14:0x55977de754b0] Op_Push             : i
[    14:0x55977de754d0] Op_plus_i           : 5 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    14:0x55977de753d0] Op_builtin          : substr [arg_count = 3]
[    14:0x55977de752b0] Op_K_printf         : [expr_count = 2] [redir_type = ""]
[    15:0x55977de75510] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    15:0x55977de75530] Op_field_spec       : 
[    15:0x55977de75590] Op_Push             : i
[    15:0x55977de755b0] Op_plus_i           : 6 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    15:0x55977de75490] Op_builtin          : substr [arg_count = 2]
[    15:0x55977de75430] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    15:0x55977de753b0] Op_store_field      : 
[    17:0x55977de75570] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    17:0x55977de754f0] Op_field_spec       : 
[    17:0x55977de755f0] Op_Push_re          : /^[ \t]*\(/
        ------[Enter] to continue or q [Enter] to quit------
[    17:0x55977de75550] Op_builtin          : match [arg_count = 2]
[      :0x55977de758b0] Op_jmp_false        : [target_jmp = 0x55977de75790]
[    20:0x55977de75630] Op_Push_i           : "%s" [MALLOC|STRING|STRCUR]
[    20:0x55977de756d0] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    20:0x55977de756b0] Op_field_spec       : 
[    20:0x55977de75730] Op_Push_i           : 1 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    20:0x55977de75770] Op_Push             : RLENGTH
[    20:0x55977de75690] Op_builtin          : substr [arg_count = 3]
[    20:0x55977de75610] Op_K_printf         : [expr_count = 2] [redir_type = ""]
[    21:0x55977de757d0] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    21:0x55977de757b0] Op_field_spec       : 
[    21:0x55977de75830] Op_Push             : RLENGTH
[    21:0x55977de75850] Op_plus_i           : 1 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    21:0x55977de75750] Op_builtin          : substr [arg_count = 2]
[    21:0x55977de756f0] Op_Push_i           : 0 [MALLOC|NUMCUR|NUMBER|NUMINT]
[    21:0x55977de75670] Op_store_field      : 
[      :0x55977de757f0] Op_jmp              : [target_jmp = 0x55977de75870]
[    24:0x55977de75790] Op_Push_i           : "($0)" [MALLOC|STRING|STRCUR]
[    24:0x55977de75710] Op_K_printf         : [expr_count = 1] [redir_type = ""]
[      :0x55977de75870] Op_no_op            : 
[      :0x55977de75390] Op_jmp              : [target_jmp = 0x55977de75310]
[      :0x55977de75810] Op_no_op            : 
[    27:0x55977de755d0] Op_K_print_rec      : [redir_type = ""]
[      :0x55977de75890] Op_no_op            : 
[      :0x55977de75950] Op_jmp              : [target_jmp = 0x55977de75230]
[      :0x55977de751f0] Op_no_op            : 
[      :0x55977de75930] Op_after_endfile    : 
[      :0x55977de751d0] Op_no_op            : 
[      :0x55977de75250] Op_atexit           : 
[      :0x55977de758d0] Op_stop             : 
gawk> q

2つを並べて配置すると、プッシュとポップが表示されます(どちらもスタックの処理に同様のアプローチを使用しているため)が、それ以上の類似性はほとんどありません。

2
Thomas Dickey