brainfuckOSを作ろうとしてみた

こんなのを見つけたのだけど
http://code.google.com/p/brainfuckos/
中が空っぽでがっかりしたので、自分で何か作ってみようかと思った。
はっきり言ってめんどくさすぎるので続きはやりませんが、こんなの作ってみました。

.code16
.equ SCREEN, 0xb800
.equ WIDTH, 80
.equ HEIGHT, 25

    jmp entry

entry:
    movw    %cs, %ax
    movw    %ax, %ds
    movw    $SCREEN, %ax
    movw    %ax, %es
    movl    $0, %edi

    movl    $WIDTH*HEIGHT*2, %ecx
1:
    movb    $0, %es:(%edi)
    incl    %edi
    decl    %ecx
    jnz     1b

    movl    $0, %edi
    movl    $main, %edx

eval_loop:
    movb    (%edx), %al
    cmpb    $0, %al
    je      fin
    cmpb    $'>, %al
    je      goforward
    cmpb    $'<, %al
    je      gobackward
    cmpb    $'+, %al
    je      increment
    cmpb    $'-, %al
    je      decrement
    cmpb    $'[, %al
    je      beginloop
    jmp     endloop
    cmpb    $'], %al
    je      endloop
    jmp     error

goforward:
    incl    %edi
    incl    %edx
    jmp     eval_loop

gobackward:
    decl    %edi
    incl    %edx
    jmp     eval_loop

increment:
    incb    %es:(%edi)
    incl    %edx
    jmp     eval_loop

decrement:
    decb    %es:(%edi)
    incl    %edx
    jmp     eval_loop

beginloop:
    movl    $0, %ecx
    movb    %es:(%edi), %al
    cmpb    $0, %al
    je      2f
1:
    incl    %edx
    jmp     eval_loop
2:
    incl    %edx
    movb    (%edx), %al
    cmpb    $'], %al
    je      3f
    cmpb    $'[, %al
    je      4f
    jmp     2b
3:
    cmpl    $0, %ecx
    je      1b
    decl    %ecx
    jmp     2b
4:
    incl    %ecx
    jmp     2b

endloop:
    movl    $0, %ecx
    movb    %es:(%edi), %al
    cmpb    $0, %al
    jne     2f
1:
    incl    %edx
    jmp     eval_loop
2:
    decl    %edx
    movb    (%edx), %al
    cmpb    $'[, %al
    je      3f
    cmpb    $'], %al
    je      4f
    jmp     2b
3:
    cmpl    $0, %ecx
    je      1b
    decl    %ecx
    jmp     2b
4:
    incl    %ecx
    jmp     2b

error:
    movl    $0, %edi
1:
    movb    errmsg(%edi), %al
    cmpb    $0, %al
    je      fin
    movb    $0x06, %ah
    movw    %ax, %es:(,%edi,2)
    incl    %edi
    jmp     1b

fin:
    hlt
    jmp     fin

errmsg:
    .string  "unknown opcode"

main:
    .ascii ">++++++++[<+++++++++>-]+"
    .ascii ">+>++++++++++[<++++++++++>-]++"
    .ascii ">-->++++++++++[<+++++++++++>-]+++"
    .ascii ">-->++++++++++[<+++++++++++>-]++++"
    .ascii ">+>++++++++++[<+++++++++++>-]+++++"
    .ascii ">+++>+++++++"
    .byte  0

    .org    0x1fe
    .byte   0x55,0xaa

リンカスクリプト

OUTPUT_FORMAT(binary)
OUTPUT_ARCH(i386)

SECTIONS {
    . = 0x7c00;
    .text : { *(.text) }
}

ビルドしてQEMUとかで実行すると

となります。
brainfuckのメモリ空間として物理メモリを使えば画面に何か表示させたり出来る訳なので、0xb800(スクリーン)にマッピングして見たのが上のコード。512バイト制限を超えるのがめんどくさかったのでブートセクタのみでやってます。
brainfuckチューリング完全なので、特定のアドレスにシステムコールとか画面リフレッシュとかの機能を持たせる最小限のコードを書けば、原理的にはbrainfuckでOSが書けるはずです。この場合入出力オペレータ".と,"はいらないですが、適当なIOポートとかにつないで遊んでみても面白いかも。