【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

2012-01-01から1年間の記事一覧

C#でJITからコールバック

C#でJITからコールバックさせてみました。PythonのコードをC#に移植したものです。 using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpA…

C#でJIT

PythonでやったJITをC#に移植しました。32bit専用です。 using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, int f…

void*とオフセット

C++

第6回 コンパイラ実装会で出た話題です。以下のコードがエラーになります。なぜ? test.cpp #include <stdlib.h> int main(void) { void *p = malloc(100); *(void **)&p[10] = reinterpret_cast<void *>(free); return 0; } コンパイル結果 $ g++ test.cpp test.cpp: In funct</void></stdlib.h>…

関数のサイズ

第6回 コンパイラ実装会で出た話題です。関数のサイズを取ろうとしたら1になりました。なぜ? test.c #include <stdio.h> int main(void) { printf("%d\n", sizeof(putchar)); return 0; } 実行結果 $ gcc test.c $ ./a.exe 1int aへのポインタが&aであるように、putc</stdio.h>…

jeとjz

x86

第6回 コンパイラ実装会で出た話題です。jzをアセンブルして逆アセンブルしたらjeになると指摘されました。なぜ変わるのか?jeとjzは別名(エイリアス)でまったく同じため、どちらを使っても同じマシン語が出力されます。理由としては、cmp命令による比較は…

第7回 コンパイラ実装会

みんなでコンパイラの実装に挑戦する勉強会です。バイナリいじりの基礎から始めて、実行ファイルを自前のコンパイラで作って動かすことを目標にします。コンパイラをきっかけにして、各種マシンコードやOSのメモリ管理について理解を深めるのが狙いです。 20…

Brainf*ckの分岐をJIT

x86の分岐命令は相対アドレス指定のため、分岐元と分岐先のアドレスが決まらなければ相対アドレスを求められません。Brainf*ckではループの先頭と末尾で分岐が出てきます。相互に分岐しているので少し複雑です。 ループの先頭 loop_begin: cmp byte ptr[esi]…

PythonによるJITで関数呼び出し

前回、Pythonでポインタアクセスする方法が分かりました。 Pythonでポインタ経由のメモリアクセス これを使ってC言語で書いたJITをPythonに移植してみます。コードの詳細は以下を参照してください。 JITで関数呼び出し 共通部 (jit.py) import sys, struct f…

Pythonでポインタ経由のメモリアクセス

Pythonでmalloc()したメモリへのアクセスを試しました。戻り値を POINTER(c_ubyte) へキャストするとアクセスできます。※ 例は32bit Windows限定のコードです。UNIX系ではlibcのロード方法が少し違います。 from ctypes import * malloc = cdll.msvcrt.mallo…

第6回 コンパイラ実装会

みんなでコンパイラの実装に挑戦する勉強会です。バイナリいじりの基礎から始めて、実行ファイルを自前のコンパイラで作って動かすことを目標にします。コンパイラをきっかけにして、各種マシンコードやOSのメモリ管理について理解を深めるのが狙いです。 20…

JITで関数呼び出し

第4回 コンパイラ実装会で出た質問です。※ 例は32bit Windows限定のコードです。【追記】Python版は以下を参照してください。 PythonによるJITで関数呼び出し 相対アドレス i386のcall命令は相対アドレスで指定するため、JITで呼ぼうとすると少し苦労します…

Brainf*ckでループ展開

第3回 コンパイラ実装会で@uho_iiotokoさんがBrainf*ckのトランスレータを実装されているとき、ちょっと面白いことが起きました。元はC言語で実装されたBrainf*ckからアセンブラへのトランスレータです。トランスレート対象がC言語でも同じ結果となるため、P…

CFunctionTypeから関数ポインタを取り出す

Pythonでは関数のアドレスを指定して呼び出せます。以下の例は適当なアドレスなので、呼び出してもエラーになります。 >>> from ctypes import * >>> f = CFUNCTYPE(None)(0x1234) >>> f() Traceback (most recent call last): File "<stdin>", line 1, in <module> Windows</module></stdin>…

Windows x64用のクロスgcc

Windows x64用のクロスgccをビルドしました。MSYSで作業しましたが、他のUNIX系OSでも同じ手順が使えるはずです。 GCC for both x64 & x86 Windows! - MinGW-w64http://mingw-w64.sourceforge.net/ 今回はmultilibを使用せずにx64専用とします。gccが依存す…

Windows NT/Alpha用のクロスgcc

32bitのAlphaのコードがどのようなものか見たくなり、Windows NT/Alpha用のクロスgccをビルドしてみました。ビルドに成功したのはgcc-3.0.4です。binutilsはビルドできるバージョンが見つからなかったため、PEバイナリは出力できません。gcc -Sでアセンブリ…

MSYSでGtk#をビルド

MSYSでのGTK+のビルドと、コマンドライン引数の問題が解決したので、ようやくGtk#のビルドに成功しました。 MSYSでGTK+をビルド (2)http://7shi.hateblo.jp/entry/2012/05/02/120012 MSYSでGTK+をビルド (3)http://7shi.hateblo.jp/entry/2012/05/06/110555 …

MSYSでGTK+をビルド (3)

先日、MSYSでGTK+ 2.24.10をビルドしました。 MSYSでGTK+をビルド (2)http://7shi.hateblo.jp/entry/2012/05/02/120012 このままでもGtk#のビルドはできますが、Gtk#のバイナリ配布物(GTK# for .NET 2.12.10)に含まれるのはGTK+ 2.16.6です。バージョンを…

MSYSのPOSIX互換レイヤをビルド

前回、MSYSのPOSIX互換レイヤをバイナリインストールして利用する方法を取り上げました。 MSYSのPOSIX互換レイヤと引数http://7shi.hateblo.jp/entry/2012/05/05/220750 今回はソースからビルドする方法です。互換レイヤを利用するだけならビルドは不要です…

MSYSのPOSIX互換レイヤと引数

MSYSのコマンド群はPOSIX互換レイヤで動いています。Cygwinから派生したGPLのライブラリで、実体は以下にあります。 /bin/msys-1.0.dll MSYSと一緒に配布されているgcc(MinGW)の出力は互換レイヤを使用しません。通常のWin32バイナリです。この挙動はCygwin…

MSYSでGTK+をビルド (2)

MSYSでGTK+をビルドする手順をまとめました。ビルド後のパッケージ一覧は前回の記事を参照してください。 MSYSでGTK+をビルド (1)http://7shi.hateblo.jp/entry/2012/04/30/181459 ビルドには非常に時間と手間が掛かります。自分でビルドしなくても本家でWin…

MSYSでGTK+をビルド (1)

Gtk#の挙動でよく分からない点があったので、GTK+を調べてみようと思い、MSYSでビルドしてみました。依存関係がとても複雑で、まるで初期のGNOMEをビルドしているような気分でした。【追記】ビルド手順をまとめました。 MSYSでGTK+をビルド (2)http://7shi.h…

MonoDevelopの衝撃

MonoDevelopを試しました。バージョンは2.8.8.4です。 http://monodevelop.com/ 予想以上にパワーアップしていて驚きました。 MonoなしにMicrosoft .NET上で動く。作成したGtk#アプリも同様。 ソリューションはVisual Studio互換。そのままVisual Studioで開…

putchar()とバッファリング

UNIX V6のprintf()は内部で1文字ずつputchar()を呼んでいます。通常は1文字ずつwriteシステムコールが呼ばれますが、特殊な細工をするとバッファリングされるようになります。今回はnmとputchar()のソースを取り上げます。 http://minnie.tuhs.org/cgi-bin/u…

PythonでJIT (Mac OS X 64bit)

先日、PythonでJITをやりましたが、32bitのWindowsに依存していました。 http://7shi.hateblo.jp/entry/2012/04/19/224650 64bitのMac OS Xに移植しました。mmapの戻り値や、munmapの引数に型を指定しているのがポイントです。指定しないとc_int(32bit)とし…

Mac OS X 64bitでシステムコール

64bitのMac OS Xでシステムコールを呼ぼうとしてハマりました。結論から言うと、システムコール番号に0x2000000を足す必要があります。詳細は以下を参照しました。 http://thexploit.com/secdev/mac-os-x-64-bit-assembly-system-calls/ exitシステムコール…

PythonでJITからコールバック

PythonでJITから文字出力するため、sys.stdout.writeのラッパーを定義してコールバックさせてみました。ラッパーのアドレスを引数で渡しています。ctypesチュートリアルにも記載されているように、libcの標準出力関数を使うとIDLEなどで正常に動作しません。…

IronPythonでJIT

前回、PythonでJITという遊びをやりました。 http://7shi.hateblo.jp/entry/2012/04/19/224650 IronPythonでもそのまま動きました。思った以上に互換性があるので驚きました。当初、バッファは(c_ubyte *32)ではなく(c_byte * 32)を使用していました。CPytho…

PythonでJIT

PythonでJITをしてみました。32bit Windowsに依存したコードです。【注】PyPyのようにPythonのコードをJITコンパイルしたわけではありません。CPythonからバイナリ直書きでネイティブコードを生成して実行しました。VBAでも同じことをやりましたが、それに比…

VBAでJITからコールバック

VBA

VBAでJITから文字出力するため、Debug.Printのラッパーを定義してコールバックさせてみました。ラッパーのアドレスを引数で渡しています。簡単に見えますが、結構ハマりました。 pushでespがずれたのを忘れて[esp+8]で引数を取ろうとした。 PutCharの引数にB…

VBAでJIT

VBA

VBAでJITをしてみました。 生成したマシン語を直接呼び出すことができないため、EnumWindows()のコールバックとして呼び出しています。 コールバックには1つだけ引数を指定できます。配列のポインタを渡して、その配列で引数と戻り値をやり取りしています。 …