出現頻度の高いアセンブラ命令を調べてみる。

 x86-64アセンブラ命令数はすでに1000前後あるみたいです。ただそんな数の命令をいちいち覚えてられないだろうという話で、実際よくみるのはほんの20命令くらい、特別なことをしないならばだいたい100命令くらい覚えていれば問題ないんじゃないの? という感じがします。

 「たのしいバイナリの歩き方」の1章でもそんな話題に少し触れています。

 まぁそもそも使用しているプログラミング言語予約語だって、全部覚えてから使い始めるわけじゃないですし。でも、じゃあどの命令を覚えておけばいいんだろう、という疑問が。

 そこで、適当なプログラムを集めて逆アセンブルし、出現するアセンブラ命令をカウントしていけばいいんじゃないかと。たくさん出現するアセンブラ命令ほど覚えておいた方がよい、ほとんど出てこないものはとりあえずスルーしておこう、みたいな。

 ではさっそく。まずC:\Program Files以下にあるEXEファイルを集めて、テキストセクション(.text)を逆アセンブル。その結果から命令(opecode)だけをカウントしていく。C:\Program Files以下にあるEXEファイルはひとそれぞれだと思いますが、ぼくの環境の結果はこんな感じでした。

01. mov  382077        11. ret   17117        21. popa  3850
02. push 294472        12. or    15490        22. shl   3826
03. call 141420        13. dec   12280        23. outsb 3801
04. add  113244        14. movzx 11270        24. ja    3599
05. int3 84545         15. jc    10458        25. insb  3138
06. cmp  83456         16. retn  10403        26. sbb   3059
07. lea  82858         17. imul  7870         27. jnl   2916
08. pop  72727         18. jnc   7311         28. arpl  2796
09. jz   62306         19. adc   6151         29. sar   2762
0a. test 45390         1a. shr   5231         2a. jg    2354
0b. jmp  44788         1b. jl    4841         2b. jo    2345
0c. jnz  44400         1c. outsv 4832         2c. js    2164
0d. xor  36666         1d. leave 4772         2d. mul   2040
0e. and  28319         1e. jna   4497         2e. neg   2003
0f. sub  24726         1f. nop   4252         2f. jns   1580
10. inc  21494         20. jng   4146         30. cwd   1489

 わりと見慣れた命令が並んでるかなーと思います。とくに左側、トップ0x10はとても身近な感じです。

 出現した各命令(上位100位まで)のカウント数をグラフにもしてみました。

f:id:b07c00:20130801033953p:plain

 ごく一部の命令はすごく出現するのに対し、まったく出現しない命令も多いですね。これは100位までを載せているので、だいたい25位以降はあまり出現しない感じです。となると、実際よくみるのは20命令くらいだなーという感覚はなんとなく当たってたのかも。

 個人的な印象としてはadd命令が少し多い気がしました。これは0x00スタートの命令なので、ゼロクリアされた領域を逆アセンブルしてしまい増えているのかなーと。int3も似た印象ですね。nopはもっと多いと思ってましたが、意外と少なかったです。

 こんな感じでアセンブラを眺めてみるのも面白いかもしれません。ちなみに5年前にも同じようなことやってますw