インラインアセンブリでBrainfu*kインタプリタ
Posted: 2011年5月03日(火) 18:27
Windows Vista SP2、Dev-C++4.9.9.2、gcc3.4.2です。
インラインアセンブリでBrainfu*kインタプリタを書こうとしています。
参考:Wikipedia
現状のコードだとコンパイルエラーがでます。
どう直せばいいかわからなくて困っています。
どうすればいいか教えていただければ幸いです。
コードは
エラーは
H:\C\bfiasm\bfiasm.c: In function `main':
H:\C\bfiasm\bfiasm.c:54: warning: use of memory input without lvalue in asm operand 1 is deprecated
C:\Users\****\AppData\Local\Temp/cceWdaaa.o(.text+0x30a):bfiasm.c: undefined reference to `putchar'
C:\Users\****\AppData\Local\Temp/cceWdaaa.o(.text+0x314):bfiasm.c: undefined reference to `getchar'
collect2: ld returned 1 exit status
です。(****はユーザー名)
よろしくお願いします。
インラインアセンブリでBrainfu*kインタプリタを書こうとしています。
参考:Wikipedia
現状のコードだとコンパイルエラーがでます。
どう直せばいいかわからなくて困っています。
どうすればいいか教えていただければ幸いです。
コードは
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[]) {
FILE* infp;
char* code;
unsigned char buffer[30000]={0};
int bufptr=0;
long size;
long runptr=0;
int nowarn=0;
/*引数チェック*/
if(argc!=2) {
fprintf(stderr,"usage:brainfu_k <program source file>\n");
return 1;
}
/*ファイル読み込み*/
infp=fopen(argv[1],"r");
if(infp==NULL) {
fprintf(stderr,"Can't open input file!\n");
return 2;
}
/*サイズの取得*/
if(fseek(infp,0,SEEK_END)) {
fclose(infp);
fprintf(stderr,"File seek error 1.\n");
return 3;
}
size=ftell(infp);
if(fseek(infp,0,SEEK_SET)) {
fclose(infp);
fprintf(stderr,"File seek error 2.\n");
return 4;
}
/*メモリの確保*/
code=malloc(size);
if(code==NULL) {
fclose(infp);
fprintf(stderr,"Malloc error.\n");
return 5;
}
/*ファイルの読み込み*/
if(fread(code,1,size,infp)==0) {
if(ferror(infp)) {
free(code);
fclose(infp);
fprintf(stderr,"File read error.\n");
return 6;
}
}
/*ファイルクローズ*/
fclose(infp);
/*インタプリタ本体*/
asm volatile(
"mov $-1,%%ecx\n\t"/*実行ポインタ*/
"mov $0,%%edx\n\t"/*メモリポインタ*/
"mov %0,%%esi\n\t"/*コード*/
"mov %1,%%edi\n\t"/*バッファ*/
"loopstart:\n\t"
"inc %%ecx\n\t"
"cmp %2,%%ecx\n\t"/*範囲をオーバーしていたら終了*/
"jae exitrun\n\t"
"cmpb $0x3E,(%%esi,%%ecx,1)\n\t"/* > */
"je pinc\n\t"
"cmpb $0x3C,(%%esi,%%ecx,1)\n\t"/* < */
"je pdec\n\t"
"cmpb $0x2B,(%%esi,%%ecx,1)\n\t"/* + */
"je minc\n\t"
"cmpb $0x2D,(%%esi,%%ecx,1)\n\t"/* - */
"je mdec\n\t"
"cmpb $0x2E,(%%esi,%%ecx,1)\n\t"/* . */
"je output\n\t"
"cmpb $0x2C,(%%esi,%%ecx,1)\n\t"/* , */
"je input\n\t"
"cmpb $0x5B,(%%esi,%%ecx,1)\n\t"/* [ */
"je startploop\n\t"
"cmpb $0x5D,(%%esi,%%ecx,1)\n\t"/* ] */
"je endploop\n\t"
"jmp loopstart\n\t"/*該当なし*/
"pinc:\n\t"/* > */
"inc %%edx\n\t"
"cmp $0,%%edx\n\t"/*範囲チェック*/
"jb exitrun\n\t"
"cmp $30000,%%edx\n\t"
"jae exitrun\n\t"
"jmp loopstart\n\t"
"pdec:\n\t"/* < */
"dec %%edx\n\t"
"cmp $0,%%edx\n\t"/*範囲チェック*/
"jb exitrun\n\t"
"cmp $30000,%%edx\n\t"
"jae exitrun\n\t"
"jmp loopstart\n\t"
"minc:\n\t"/* + */
"incb (%%edi,%%edx,1)\n\t"
"jmp loopstart\n\t"
"mdec:\n\t"/* - */
"decb (%%edi,%%edx,1)\n\t"
"jmp loopstart\n\t"
"output:\n\t"/* . */
"mov $0,%%ebx\n\t"
"mov (%%edi,%%edx,1),%%bl\n\t"
"push %%ebx\n\t"
"call putchar\n\t"
"jmp loopstart\n\t"
"input:\n\t"/* , */
"call getchar\n\t"
"mov %%eax,(%%edi,%%edx,1)\n\t"
"jmp loopstart\n\t"
"startploop:\n\t"/* [ */
"mov $1,%%eax\n\t"
"searchend:\n\t"
"inc %%ecx\n\t"
"cmp %2,%%ecx\n\t"/*範囲をオーバーしていたら終了*/
"jae exitrun\n\t"
"cmpb $0x5B,(%%esi,%%ecx,1)\n\t"/* [ */
"je plus\n\t"
"cmpb $0x5D,(%%esi,%%ecx,1)\n\t"/* ] */
"je minus\n\t"
"jmp searchend\n\t"
"plus:\n\t"
"inc %%eax\n\t"
"jmp searchend\n\t"
"minus:\n\t"
"dec %%eax\n\t"
"cmp $0,%%eax\n\t"
"jbe loopstart\n\t"
"jmp searchend\n\t"
"endploop:\n\t"/* ] */
"mov $1,%%eax\n\t"
"searchend2:\n\t"
"dec %%ecx\n\t"
"cmp $0,%%ecx\n\t"/*範囲をオーバーしていたら終了*/
"jb exitrun\n\t"
"cmpb $0x5B,(%%esi,%%ecx,1)\n\t"/* [ */
"je minus2\n\t"
"cmpb $0x5D,(%%esi,%%ecx,1)\n\t"/* ] */
"je plus2\n\t"
"jmp searchend2\n\t"
"plus2:\n\t"
"inc %%eax\n\t"
"jmp searchend2\n\t"
"minus2:\n\t"
"dec %%eax\n\t"
"cmp $0,%%eax\n\t"
"jbe loopstart\n\t"
"jmp searchend2\n\t"
"exitrun:\n\t"/*終了*/
:
: "m"(code),"m"(buffer),"m"(size)
: "%eax","%ebx","%ecx","%edx","%esi","%edi");
/*メモリの開放*/
free(code);
return 0;
}
H:\C\bfiasm\bfiasm.c: In function `main':
H:\C\bfiasm\bfiasm.c:54: warning: use of memory input without lvalue in asm operand 1 is deprecated
C:\Users\****\AppData\Local\Temp/cceWdaaa.o(.text+0x30a):bfiasm.c: undefined reference to `putchar'
C:\Users\****\AppData\Local\Temp/cceWdaaa.o(.text+0x314):bfiasm.c: undefined reference to `getchar'
collect2: ld returned 1 exit status
です。(****はユーザー名)
よろしくお願いします。