加载中…
个人资料
liang
liang
  • 博客等级:
  • 博客积分:0
  • 博客访问:54,322
  • 关注人气:22
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
正文 字体大小:

用汇编语言写的计算机语言BrainFuck的编译器

(2013-05-29 21:42:00)

用c语言写的计算机语言BrainFuck的编译器
http://blog.sina.com.cn/s/blog_6adc92d70100u4o0.html

 

我碰巧看到用汇编语言为Linux写的计算机语言BrainFuck的编译器
http://www.muppetlabs.com/~breadbox/software/tiny/bf.asm.txt
稍微修改了一下,把32位改成16位,用int 10 和 int 16 代替 int 80 ,以便于在dos下运行

 

程序写得巧妙,风格不好。这样子写法叫人家怎么看得懂呀
没有严格测试,大概有那个意思就得了
code segment
     assume cs:code,ds:code,es:code,ss:code
textorg = 100h
dataorg = 2000h
     org textorg   ;100       
emitputchar:
        mov si,offset putchar
        jmp emit6byte
emitgetchar:
        add si,4
        movsb
emit6byte:
        movsw
        movsw
emit2byte:
        movsb
emit1byte:
        movsb
compile:
        lea si,[e]
        mov bp,di
        jmp getchar
eof:
        movsw
        movsw                            

        mov ax,0e0ah
        int 10h
        mov ax,0e0dh
        int 10h

        pop bx

        mov di,bx
        mov cx,1000
        mov al,0
        rep stosb

        jmp start
bracket:
        mov al,0e9h ;jmp
        inc bp
        push bp
        stosw
        jmp emit1byte
f:
        dd 0
putchar:
        mov al,[bx]
        mov ah,0eh
        int 10h
e:
        mov ah,4ch
        int 21h

        inc bx
        dec bx
        inc byte ptr [bx]
        dec byte ptr [bx]
getchar:
        mov ax,0
        int 16h
        mov byte ptr [bx],al
push ax
      mov ah,0eh
      int 10h
pop ax     
        cmp al,0dh
        jz eof
        add si,4
        cmp al,'>'
        jz emit1byte
        inc si
        cmp al,'<'
        jz emit1byte
        inc si
        sub al,'+'
        jz emit2byte
        dec al ;,
        jz emitgetchar
        inc si
        inc si
        dec al  ; -
        jz emit2byte
        dec al ;.
        jz emitputchar
        cmp al,'[' - '.'
        jz bracket
        cmp al,']' - '.'
        jz endbracket
relay:
        jmp compile
endbracket:
        mov ax,3f80h
        stosw
        xor al,al
        stosb
        mov ax,850fh
        stosw
        lea si,[di - 7]
        pop bp
        sub si,bp
        mov [bp],si
        sub bp,di
        mov ax,bp
        stosw
        jmp relay
start:
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ss,ax
        mov sp,0fff0h
codebuf:
        mov bx,dataorg ;2000h
        push bx
        mov bx,offset f
        lea di,[codebuf]
        jmp relay
code ends
     end start
    原来用linux的读写文件,我偷懒,用int 16读键盘,用int 10显示。
    为什么把start初始化放在最后?因为编译后的机器码就放在这儿,把初始化代码冲掉了。di指向codebuf

,si指向退出代码的机器码处。
    我先写退出命令,就是回车。测到回车0dh值,转eof行,把ah=4c int 21的机器码粘贴入codebuf处,jmp

转start,执行退出。
    再写>命令,si加4指向inc bx的机器码处,粘贴入buf,< + - 命令相应地移si值
    ,和. 命令,也是让si指向机器码处,粘贴入buf,只不过多粘贴几个字节。这时发现[bx]无值,就添加一

句mov byte ptr [bx],al 满足int 16的值在al中的情况。
    最后写[和]命令,[命令转bracket处,先把jmp的机器码e9粘贴入buf,再空出两个字节,供将来遇]时回填

地址值,push bp 保存地址,bp加一是去掉jmp机器码占的一个字节。]命令在endbracket,把 cmp [bx],0 和

jnz 的机器码,粘贴入buf,再计算转移地址值,粘贴入buf,以及回填入[指命处。
    全写完后发现敲键盘无回显,所以加个int 10 ,后发现显示的值和输入在同一行中,所以加了个回车。测

试时发现内存不干净,再在jmp start前加了个清内存。
    运行了显示ASCII码表的程序++++++++++++++++[->++++++++++++++++<]>-[->+.<]看到有显示,得过且过,

不修改了,反正是玩玩的
--------------------------
--------------------------
AoGo汇编小站 http://www.aogosoft.com 的 AoGo 结婚旅行回来,看到我介绍BrainFuck,问道:这在什么地

方有用处呢?
我回答:弄着玩儿,没有用处
--------------------------
--------------------------
最近网上流行普通青年、文艺青年和213青年。我编了一组:

普通程序员
#include
main()
{
    printf("Hello, world\n");
}

 

文艺程序员
#include
int n[]=0x48,0x65,0x6c,0x6c,0x6f,0x2c,0x20,0x77,0x6f,0x72,0x6c,0x64,0x21,0x0a,0x00},*m=n;main(n)

{if(putchar(*m)!='\0')main(m++);}

 

213程序员
++++++[->++++++++++++<]>.----[--<+++>]<-.+++++++..+++.[--->+<]>-----.---[-<+++>]<.---[--->++++<]

>-.+++.------.--------.-[---<+>]<.[--->+<]>-.

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有