⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbvm.c

📁 c编译器实现
💻 C
字号:
/* *  FBCC - A simple C compiler. *  *  Copyright (c) 1996 Fabrice Bellard * *  Contact addresses: *  mail: Fabrice Bellard, 451 chemin du mas de Matour, 34790 Grabels, France *  email: bellard@email.enst.fr *  url: http://www.enst.fr/~bellard * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include <stdio.h>#include "fbvmspec.h"#include "fbvminstr.h"/* #define DEBUG */typedef unsigned char VMCodeData;typedef unsigned char VMData;typedef int VMStackData;#if VM_LITTLE_ENDIAN == 0static void mput_i(unsigned char *p,unsigned int a){	 p[0]=a >> 24;	 p[1]=a >> 16;	 p[2]=a >> 8;	 p[3]=a;}static int mget_i(unsigned char *p){	 return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + (p[3]);}#else static void mput_i(unsigned char *p,unsigned int a){	 p[3]=a >> 24;	 p[2]=a >> 16;	 p[1]=a >> 8;	 p[0]=a;}static int mget_i(unsigned char *p){	 return (p[3]<<24) + (p[2]<<16) + (p[1]<<8) + (p[0]);}#endifint vm_argc;char **vm_argv;void VMLibCall(int *sp,int *bp,int c){	 int a;	 int *p;	 switch(c) {		case 0:			/* getvars */			p=(void *)bp[-3];			p[0]=(int)stdin;			p[1]=(int)stdout;			p[2]=(int)stderr;			p[3]=vm_argc;			p[4]=(int)vm_argv;			sp[0]=0;			break;		case 1:			/* malloc */			sp[0]=(int)malloc(bp[-3]);			break;		case 2:			/* free */			free((void *)bp[-3]);			sp[0]=0;			break;		case 3:			/* exit */			exit(bp[-3]);			break;		case 4:			/* realloc */			p=(void *)bp[-3];			a=bp[-4];			sp[0]=(int) realloc(p,a);			break;		case 5:			/* fputc */			sp[0]=fputc(bp[-3],(FILE *)bp[-4]);			break;		case 6:			/* fgetc */			sp[0]=fgetc((FILE *)bp[-3]);			break;		case 7:			/* fread */			sp[0]=fread((void *)bp[-3],bp[-4],bp[-5],(FILE *)bp[-6]);			break;		case 8:			/* fwrite */			sp[0]=fwrite((void *)bp[-3],bp[-4],bp[-5],(FILE *)bp[-6]);			break;		case 9:			/* ferror */			sp[0]=ferror((FILE *)bp[-3]);			break;		case 10:			/* fopen */			sp[0]=(int)fopen((char *)bp[-3],(char *)bp[-4]);			break;		case 11:			/* fclose */			sp[0]=fclose((FILE *)bp[-3]);			break;		default:			fprintf(stderr,"libcall %d non impl閙ent閈n",c);			break;	 }}void VMExec(VMCodeData *init_ip,VMStackData *init_sp){	 register VMCodeData *ip;	 register int *sp;	 int *bp;	 int op_code;	 VMCodeData *ip1;	 int a,b;	 	 ip=init_ip;	 sp=init_sp;	 bp=init_sp;	 	 while (1) {			op_code=*ip++;#ifdef DEBUG			fprintf(stderr,"debug: sp=%d bp=%d sp[0]=%d %s\n",							sp-init_sp,bp-init_sp,sp[0],vm_instr_str[op_code]);#endif			switch(op_code) {				 /* memory read */			 case ld_b:				 sp[0]=*((char *)sp[0]);				 break;			 case ld_ub:				 sp[0]=*((unsigned char *)sp[0]);				 break;			 case ld_w:				 sp[0]=*((short *)sp[0]);				 break;			 case ld_uw:				 sp[0]=*((unsigned short *)sp[0]);				 break;			 case ld_i:				 sp[0]=*((int *)sp[0]);				 break;				 				 /* memory write */			 case st_i:				 *((int *)sp[0])=sp[-1];				 sp--;				 break;			 case st_w:				 *((short *)sp[0])=sp[-1];				 sp--;				 break;			 case st_b:				 *((char *)sp[0])=sp[-1];				 sp--;				 break;				 				 /* load immediate pointers */			 case libp_i:				 sp++;				 sp[0]=(int)bp + mget_i(ip);				 ip+=4;				 break;				 /* load immediate data */			 case li_i:				 sp++;				 sp[0]=mget_i(ip);				 ip+=4;				 break;				 /* arithm閠ique */			 case add_i:				 sp[-1]+=sp[0];				 sp--;				 break;			 case sub_i:				 sp[-1]-=sp[0];				 sp--;				 break;			 case mul_i:				 sp[-1]*=sp[0];				 sp--;				 break;			 case div_i:				 sp[-1]/=sp[0];				 sp--;				 break;			 case mod_i:				 sp[-1]%=sp[0];				 sp--;				 break;			 case mul_ui:				 (unsigned int)sp[-1]*=(unsigned int)sp[0];				 sp--;				 break;			 case div_ui:				 (unsigned int)sp[-1]/=(unsigned int)sp[0];				 sp--;				 break;			 case mod_ui:				 (unsigned int)sp[-1]%=(unsigned int)sp[0];				 sp--;				 break;			 case neg_i:				 sp[0]=-sp[0];				 break;				 /* op閞ations logiques */			 case and_i:				 sp[-1]&=sp[0];				 sp--;				 break;			 case or_i:				 sp[-1]|=sp[0];				 sp--;				 break;			 case xor_i:				 sp[-1]^=sp[0];				 sp--;				 break;			 case not_i:				 sp[0]=~sp[0];				 break;			 case shl_i:				 sp[-1]<<=sp[0];				 sp--;				 break;			 case shr_i:				 sp[-1]>>=sp[0];				 sp--;				 break;			 case shr_ui:				 (unsigned int)sp[-1]>>=sp[0];				 sp--;				 break;				 				 /* conversions */			 case cvt_i_b:				 sp[0]=(char)sp[0];				 break;			 case cvt_b_i:			 case cvt_i_ub:				 sp[0]=(unsigned char)sp[0];				 break;			 case cvt_i_w:				 sp[0]=(short)sp[0];				 break;			 case cvt_w_i:			 case cvt_i_uw:				 sp[0]=(unsigned short)sp[0];				 break;				 				 				 				 /* tests */			 case cmplt_i:				 sp[-1]=sp[-1] < sp[0];				 sp--;				 break;			 case cmple_i:				 sp[-1]=sp[-1] <= sp[0];				 sp--;				 break;			 case cmpgt_i:				 sp[-1]=sp[-1] > sp[0];				 sp--;				 break;			 case cmpge_i:				 sp[-1]=sp[-1] >= sp[0];				 sp--;				 break;			 case cmplt_ui:				 sp[-1]=(unsigned int)sp[-1] < (unsigned int)sp[0];				 sp--;				 break;			 case cmple_ui:				 sp[-1]=(unsigned int)sp[-1] <= (unsigned int)sp[0];				 sp--;				 break;			 case cmpgt_ui:				 sp[-1]=(unsigned int)sp[-1] > (unsigned int)sp[0];				 sp--;				 break;			 case cmpge_ui:				 sp[-1]=(unsigned int)sp[-1] >= (unsigned int)sp[0];				 sp--;				 break;			 			 case cmpeq_i:				 sp[-1]=sp[-1] == sp[0];				 sp--;				 break;			 case cmpne_i:				 sp[-1]=sp[-1] != sp[0];				 sp--;				 break;				 				 /* subroutines */			 case jsr:				 a=mget_i(ip);				 ip+=4;				 ip1=(void *)sp[0];				 sp[0]=(int)ip;				 sp[1]=(int)bp;				 sp[2]=a;				 sp+=2;				 ip=ip1;				 bp=sp;				 break;			 case rts:				 a=sp[0];  /* valeur retourn閑 */				 sp=bp;				 ip=(void *)sp[-2];				 bp=(void *)sp[-1];				 b=sp[0];				 (int)sp=(int)sp-(b+8);				 sp[0]=a;				 break;			 /* jumps */			 case jmp:				 ip1=(void *)mget_i(ip);				 ip=ip1;				 break;			 			 case jeq_i:				 ip1=(void *)mget_i(ip);				 ip+=4;				 if (sp[0]==0) ip=ip1;				 sp--;				 break;			 			 case jne_i:				 ip1=(void *)mget_i(ip);				 ip+=4;				 if (sp[0]!=0) ip=ip1;				 sp--;				 break;			 				 /* gestion de la pile */			 case addsp:				 a=mget_i(ip);				 ip+=4;				 sp=(void *)((int)sp + a);				 break;				 			 case dup:				 sp++;				 sp[0]=sp[-1];				 break;				 			 case pop:				 sp--;				 break;				 				 /* appels systeme */			 case libcall:				 a=mget_i(ip);				 ip+=4;				 sp++;				 VMLibCall(sp,bp,a);				 break;				 				 /* gestion des switchs : inspir

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -