だんだん、難易度を上げていく。とはいっても、まだ、基本情報技術者試験レベル(このくらいのレベルだったと思う)。新人のころに、満点がとれるレベルまで勉強したのだが、うそみたいだ*1。
さてさて、まずは、バブルソート(単純交換ソート)のプログラムを書く。さすがに「バブルソートってなんだっけ?」というレベルまでは、落ちていなかった。
#include "stdafx.h" int a[7] = { 2,3,6,5,1,0,4 }; void swap(int a[], int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; } void bubbleSort(int a[], int size) { for (int i = 0; i < size; i++) { for (int j = 0; j < i; j++) { if (a[i] < a[j]) swap(a, i, j); } } } void printArray(int a[], int size) { for (int i = 0; i < size; i++) { printf("%d ", a[i]); } printf("\r\n"); } void main() { int size = sizeof(a) / sizeof(a[0]); printArray(a, size); bubbleSort(a, size); printArray(a, size); }
早速、逆アセンブル。bubbleSort 関数を見てみる。25 行と短い。なんとかなりそうだ。
ここで、スワップする(値を入れ替える)ときのスタックの様子は、次のようになっている。
もともと、たいした処理をしていないので、ゆっくり読めば、まず理解できる。各行の解説は、図の中に示した通りなので、割愛する。
最後に、ここで出てくる重要な命令*2を、まとめておく。
- 論理演算命令
- ジャンプ命令(比較した値が符号ありの 4 バイトデータ)→ フラグは変化しない
- その他の命令
そろそろ、まとまった量を読んでみようかな。
*1:それもそのはず。数年間、プログラミングから離れただけで、「コンストラクタってなんだっけ?」というレベルになってしまった。しばらくプログラミングをしていたら、ある程度、感覚は戻ってきたのだが。衝撃だった。
*2:データ転送命令である MOV、算術演算命令である COMP と INC、スタック操作命令である PUSH と POP は、さすがにもういいでしょう。
*3:オーバーフローをおこしておらず、かつ、演算結果が正の場合。
*4:オーバーフローをおこしており、かつ、演算結果が負の場合。
*5:演算結果が "0" ではない場合。
*6:基本は、JGE と同様。結果は "0" でもよいので、ZF の判定がない。
*7:データ型のアラインメントとは何か,なぜ必要なのか? が詳しい。ちゃんと解説してくれている人がいるんだ。