qsort の callback の書き方

http://d.hatena.ne.jp/Ozy/20070123#c1169554585

を見て、前から qsort の callback 関数は関数書くより機械語埋めた方が短くなるんじゃないかなーと思ってたのを思い出しました。

int a[] = { 1, 3, 9, 2, 7, 4, 5, 8, 6 };
int main() {
    int i;
    qsort(a,sizeof(a)/4,4,"\x8b\0+\x02\xc3");
    for (i = 0; i < sizeof(a)/4; i++) {
        printf("%d ", a[i]);
    }
    puts("");
}

これ、うちではちゃんと 1 2 3 4 5 6 7 8 9 という出力が得られました。というわけで qsort の第四引数は関数ポインタじゃなくて文字列です。

メモリ保護かかってないのが前提の上に、 x86 依存の上に libc の実装だとか libc をコンパイルしたコンパイラにもよるでしょう。というのはこのコードは、

        movl (%eax), %eax
        subl (%edx), %eax
        ret

なんていうものだったりして、第一引数と第二引数がたまたま EAX と EDX に入ってることに依存してます。

ちなみに PKU で使えるかなーと思って PKU2371 にこのテクニックを用いてみたところ、 Runtime Error 。 .data セクションに置いても同じ。まぁ Windows だとキチンとメモリ保護かかってるってことでしょう。あと長くなるけどなーと思って __attribute まわりをいじってみたりしましたがうまくいかず。なんかうまいことやればいける方法もあるかもしれないなぁとは思います。

追記: PKU についての記述は取り消します。たぶんいける。ちょいと Windows マシン修理タイムです。

追記:

http://d.hatena.ne.jp/MaD/20070125#1169753158

PPC でやってくださった方が。 PPC にしては短いなぁというような。引数がレジスタ渡しなのはありがたいですね。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h