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

📄 myvm.c

📁 一个小型的操作系统,采用gcc进行开发,几千行的代码,方便初学者学习
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    while (!(ch > ' ' || feof(data) || *ps != running));    if (*ps == running) {	if (feof(data))	    *ps = nodata;	else {	    switch (ch) {	    case '-':		negative = true;		readchar(data, &ch, ps);		break;	    case '+':		negative = false;		readchar(data, &ch, ps);		break;	    }	    if (!isxdigit(ch))		*ps = baddata;	    else {		while (isxdigit(ch) && *ps == running) {		    if (hexdigit(ch) < base			&& num <= (maxint - hexdigit(ch)) / base)			num = base * num + hexdigit(ch);		    else			*ps = baddata;		    readchar(data, &ch, ps);		}	    }	}	if (negative)	    num = -num;	if (num > 0)	    return num % 256;	else	    return (256 - abs(num) % 256) % 256;	/* negtive is represented in 2's complement */    }    return 0;}/* the core for running machine code in mem */void execute(MC_bytes initpc, FILE * data, FILE * results, bool tracing){    MC_bytes pcnow;		/* to save the preceded value of PC while current opcode is been executed */    MC_bytes carry;		/* to save carry bit in addition or subtraction operation */    MC_bytes number;    cpu.z = false;    cpu.p = false;    cpu.c = false;		/* cpu's flag register initialization */    cpu.a = 0;    cpu.x = 0;    cpu.sp = 0;			/* initialization for sp */    cpu.bp = 0;			/* initialization for bp */    cpu.pc = initpc;		/* initialization for pc with initpc supplied by caller */    ps = running;		/* initialization for cpu's running state */    /* the following loop demonstrates or simulates CPU'S behaviour, code fetching ->analyzing */    /* -> executing, in the process of instruction executing, until the HALT executed or */    /* runtime error occured */    do {	cpu.ir = mem[cpu.pc];	/* fetch a opcode from the memory indicated by pc to ir */	pcnow = cpu.pc;		/* to save the preceded value of PC */	increment(&cpu.pc);	/* PC indicates the next opcode which will be executed */	if (tracing)	    trace(results, pcnow);	/* if trace enable, output cpu's internal registers */	switch (cpu.ir) {	/* which opcode is now in cpu.ir */	case MC_nop:	    break;		/* nop, no operation, return directly without any operation */	case MC_clra:		/* clear register A */	    cpu.a = 0;	    break;	case MC_clrc:		/* clear carry bit */	    cpu.c = false;	    break;	case MC_clrx:		/* clear index register X */	    cpu.x = 0;	    break;	case MC_cmc:		/* complemented carry bit */	    cpu.c = !cpu.c;	    break;	case MC_inc:		/* A=A+1, certain flag may be affected */	    increment(&cpu.a);	    setflags(cpu.a);	    break;	case MC_dec:		/* A=A-1, certain flag may be affected */	    decrement(&cpu.a);	    setflags(cpu.a);	    break;	case MC_incx:		/* X=X+1, certain flag may be affected */	    increment(&cpu.x);	    setflags(cpu.x);	    break;	case MC_decx:		/* x=x-1, certain flag may be affected */	    decrement(&cpu.x);	    setflags(cpu.x);	    break;	case MC_tax:		/* X=A */	    cpu.x = cpu.a;	    break;	case MC_ini:		/* get number in decimal and send to A,certain flag may be affected */	    cpu.a = getnumber(data, 10, &ps);	    setflags(cpu.a);	    break;	case MC_inb:		/* get number in binary and send to A,certain flag may be affected */	    cpu.a = getnumber(data, 2, &ps);	    setflags(cpu.a);	    break;	case MC_inh:		/* get number in hexadecimal and send to A,certain flag may be affected */	    cpu.a = getnumber(data, 16, &ps);	    setflags(cpu.a);	    break;	case MC_ina:		/* get ascii char and send to A,certain flag may be affected */	    {		char ascii;		readchar(data, &ascii, &ps);		if (feof(data))		    ps = nodata;		else {		    cpu.a = ascii;		    setflags(cpu.a);		}	    }	    break;	case MC_oti:		/* output the content of register A in decimal */	    if (cpu.a < 128)		fprintf(results, "%d ", cpu.a);	    else		fprintf(results, "%d ", cpu.a - 256);	    if (tracing)		putc('\n', results);	    break;	case MC_oth:		/* output the content of register A in hexadecimal */	    fprintf(results, "%02X ", cpu.a);	    if (tracing)		putc('\n', results);	    break;	case MC_otc:		/* output the content of register A in unsigned decimal */	    fprintf(results, "%d ", cpu.a);	    if (tracing)		putc('\n', results);	    break;	case MC_otb:		/* output the content of register A in unsigned binary */	    {		int bits[8];		int loop;		number = cpu.a;		for (loop = 0; loop <= 7; loop++) {		    bits[loop] = number % 2;		    number /= 2;		}		for (loop = 7; loop >= 0; loop--)		    fprintf(results, "%d", bits[loop]);		putc(' ', results);		if (tracing)		    putc('\n', results);	    }	    break;	case MC_ota:		/* output the content of register A in ascii char */	    putc(cpu.a, results);	    if (tracing)		putc('\n', results);	    break;	case MC_push:		/* push A's content to stack: SP=SP-1,[SP]=A */	    decrement(&cpu.sp);	    mem[cpu.sp] = cpu.a;	    break;	case MC_pop:		/* pop stack to A: A=[SP],SP=SP+1, certain flag may be affected */	    cpu.a = mem[cpu.sp];	    increment(&cpu.sp);	    setflags(cpu.a);	    break;	case MC_shl:		/* A's bit shift leftly in turn, MSB->C bit,certain flag may be affected */	    cpu.c = (cpu.a * 2 > 255);	    cpu.a = cpu.a * 2 % 256;	    setflags(cpu.a);	    break;	case MC_shr:		/* A's bit shift rightly in turn,LSB->C bit ,certain flag may be affected */	    cpu.c = cpu.a & 1;	    cpu.a /= 2;	    setflags(cpu.a);	    break;	case MC_ret:		/* return from callee,PC=[SP], SP=SP+1 */	    cpu.pc = mem[cpu.sp];	    increment(&cpu.sp);	    break;	case MC_halt:		/* halt MYVM */	    ps = finished;	    break;	case MC_lda:		/* LDA B, A=[B], certain flag may be affected */	    cpu.a = mem[mem[cpu.pc]];	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_ldx:		/* LDX B, A=[X+B] , certain flag may be affected */	    cpu.a = mem[index()];	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_ldi:		/* LDI B,A=ImmB,certain flag may be affected */	    cpu.a = mem[cpu.pc];	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_lsp:		/* LSP B, SP=[ImmB] */	    cpu.sp = mem[mem[cpu.pc]];	    increment(&cpu.pc);	    break;	case MC_lspi:		/* LSPI B,SP=ImmB */	    cpu.sp = mem[cpu.pc];	    increment(&cpu.pc);	    break;	case MC_sta:		/* STA B,[ImmB]=A */	    mem[mem[cpu.pc]] = cpu.a;	    increment(&cpu.pc);	    break;	case MC_stx:		/* STX B, [X+B]=A */	    mem[index()] = cpu.a;	    increment(&cpu.pc);	    break;	case MC_add:		/* ADD B, A=A+[ImmB],certain flag may be affected */	    cpu.c = (cpu.a + mem[mem[cpu.pc]] > 255);	    cpu.a = (cpu.a + mem[mem[cpu.pc]]) % 256;	/* result may be 0~255 */	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_adx:		/* ADX B, A=A+[X+ImmB],certain flag may be affected */	    cpu.c = (cpu.a + mem[index()] > 255);	    cpu.a = (cpu.a + mem[index()]) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_adi:		/* ADI B, A=A+ImmB, certain flag may be affected */	    cpu.c = (cpu.a + mem[cpu.pc] > 255);	    cpu.a = (cpu.a + mem[cpu.pc]) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_adc:		/* ADC B, A=A+C+[ImmB],certain flag may be affected */	    carry = cpu.c;	    cpu.c = (cpu.a + mem[mem[cpu.pc]] + carry > 255);	    cpu.a = (cpu.a + mem[mem[cpu.pc]] + carry) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_acx:		/* ACX B ,A=A+C+[X+ImmB],certain flag may be affected */	    carry = cpu.c;	    cpu.c = (cpu.a + mem[index()] + carry > 255);	    cpu.a = (cpu.a + mem[index()] + carry) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_aci:		/* ACI B, A=A+C+ImmB, certain flag may be affected */	    carry = cpu.c;	    cpu.c = (cpu.a + mem[cpu.pc] + carry > 255);	    cpu.a = (cpu.a + mem[cpu.pc] + carry) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_sub:		/* SUB B, A=A-[ImmB],certain flag may be affected */	    cpu.c = (cpu.a < mem[mem[cpu.pc]]);	    cpu.a = (cpu.a - mem[mem[cpu.pc]] + 256) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_sbx:		/* SBX B, A=A-[X+ImmB],certain flag may be affected */	    cpu.c = (cpu.a < mem[index()]);	    cpu.a = (cpu.a - mem[index()] + 256) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_sbi:		/* SBI B, A=A-ImmB, certain flag may be affected */	    cpu.c = (cpu.a < mem[cpu.pc]);	    cpu.a = (cpu.a - mem[cpu.pc] + 256) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_sbc:		/* SBC B, A=A-C-[ImmB],certain flag may be affected */	    carry = cpu.c;	    cpu.c = (cpu.a < mem[mem[cpu.pc]] + carry);	    cpu.a = (cpu.a - mem[mem[cpu.pc]] - carry + 256) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_scx:		/* SCX B, A=A-C-[X+ImmB],certain flag may be affected */	    carry = cpu.c;	    cpu.c = (cpu.a < mem[index()] + carry);	    cpu.a = (cpu.a - mem[index()] - carry + 256) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_sci:		/* SCI B, A=A-C-ImmB, certain flag may be affected */	    carry = cpu.c;	    cpu.c = (cpu.a < mem[cpu.pc] + carry);	    cpu.a = (cpu.a - mem[cpu.pc] - carry + 256) % 256;	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_cmp:		/* CMP B, compare A with [B] to affect certain flag */	    cpu.c = (cpu.a < mem[mem[cpu.pc]]);	    setflags((cpu.a - mem[mem[cpu.pc]] + 256) % 256);	    increment(&cpu.pc);	    break;	case MC_cpx:		/* CPX B, compare A with [X+ImmB] to affect certain flag */	    cpu.c = (cpu.a < mem[index()]);	    setflags((cpu.a - mem[index()] + 256) % 256);	    increment(&cpu.pc);	    break;	case MC_cpi:		/* CPI B, compare A with ImmB to affecte certain flag */	    cpu.c = (cpu.a < mem[cpu.pc]);	    setflags((cpu.a - mem[cpu.pc] + 256) % 256);	    increment(&cpu.pc);	    break;	case MC_ana:		/* ANA B, A=A&[ImmB],bitwise and A with [ImmB] to affecte certain flag */	    cpu.a &= mem[mem[cpu.pc]];	    increment(&cpu.pc);	    setflags(cpu.a);	    cpu.c = false;	    break;	case MC_anx:		/* ANX B, A=A&[X+ImmB], bitwise and A with [X+ImmB] to affecte certain flag */	    cpu.a &= mem[index()];	    increment(&cpu.pc);	    setflags(cpu.a);	    cpu.c = false;	    break;	case MC_ani:		/* ANI B,A=A&ImmB  bitwise and A with ImmB to affecte certain flag */	    cpu.a &= mem[cpu.pc];	    increment(&cpu.pc);	    setflags(cpu.a);	    cpu.c = false;	    break;	case MC_ora:		/* ORA B, A=A|[ImmB],bitwise and A with [ImmB] to affecte certain flag */	    cpu.a |= mem[mem[cpu.pc]];	    increment(&cpu.pc);	    setflags(cpu.a);	    cpu.c = false;	    break;	case MC_orx:		/* ORX B,A=A|[X+ImmB], bitwise or A with [X+ImmB] to affecte certain flag */	    cpu.a |= mem[index()];	    increment(&cpu.pc);	    setflags(cpu.a);	    cpu.c = false;	    break;	case MC_ori:		/* ORI B,A=A|ImmB ,bitwiae or A with ImmB to affect certain flag */	    cpu.a |= mem[cpu.pc];	    increment(&cpu.pc);	    setflags(cpu.a);	    cpu.c = false;	    break;	case MC_jmp:		/* JMP B, jump to address B unconditionally */	    cpu.pc = mem[cpu.pc];	    break;	case MC_bze:		/* BZE B, jmup to address B if Z=1, else goto next instruction */	    if (cpu.z)		cpu.pc = mem[cpu.pc];	    else		increment(&cpu.pc);	    break;	case MC_bnz:		/* BZE B, jmup to address B if Z=0, else goto next instruction */	    if (!cpu.z)		cpu.pc = mem[cpu.pc];	    else		increment(&cpu.pc);	    break;	case MC_bpz:		/* BPZ B, jump to address B if P=1(positive),else goto next instruction */	    if (cpu.p)		cpu.pc = mem[cpu.pc];	    else		increment(&cpu.pc);	    break;	case MC_bng:		/* BNG B, jump to address B if P=0(positive),else goto next instruction */	    if (!cpu.p)		cpu.pc = mem[cpu.pc];	    else		increment(&cpu.pc);	    break;	case MC_bcs:		/* BCS B, jump to address B if C=1(carried),else goto next instruction */	    if (cpu.c)		cpu.pc = mem[cpu.pc];	    else		increment(&cpu.pc);	    break;	case MC_bcc:		/* BCC B, jump to address B if C=0(not carried),else goto next instruction */	    if (!cpu.c)		cpu.pc = mem[cpu.pc];	    else		increment(&cpu.pc);	    break;	case MC_jsr:		/* JSR B, jump subRoutine,push retAddr,B->PC */	    decrement(&cpu.sp);	    mem[cpu.sp] = (cpu.pc + 1) % 256;	/* push return address */	    cpu.pc = mem[cpu.pc];	    break;	case MC_tsp:		/* TSP, Transfer SP to A, A=SP */	    cpu.a = cpu.sp;	    setflags(cpu.a);	    break;	case MC_lbpi:		/* LBPI B,A=[BP+ImmB],Load A with [BP+ImmB] */	    cpu.a = mem[cpu.bp + mem[cpu.pc]];	    increment(&cpu.pc);	    setflags(cpu.a);	    break;	case MC_fbpi:		/* FBPI B, BP=ImmB ,Feed BP with ImmB */	    cpu.bp = mem[cpu.pc];	    increment(&cpu.pc);	    break;	case MC_tbp:		/* TBP, A=BP, Transfer BP to A */	    cpu.a = cpu.bp;	    setflags(cpu.a);	    break;	case MC_tsb:		/* TSB, BP=SP, Transfer Sp to Bp */	    cpu.bp = cpu.sp;	    break;	case MC_tabp:		/* TABP, BP=A, Transfer A to Bp */	    cpu.bp = cpu.a;	    break;	default:	    ps = badop;	    break;	}    }    while (ps == running);    if (ps != finished)	runtime_error(results, pcnow);}void runvm(){    FILE *data, *results;    char filename[20];    newsuffix(srcfile, "out", filename);    results = fopen(filename, "a");	/* create a new file named filename */    execute(0 % 256, NULL, results, 0);	/* do it! */    fclose(results);    /* fclose(data); */}static void logo(){    printf("\nMYVM Virtual Machine Premiere, Version 0.11a \n");    printf("\tCopyright under GPL 2002,2003, Snallie@tom.com\n");    printf("\tA contribution dedicated to Snixos, 2004.6\n\n");}#ifdef _NATIVEmain(int argc, char *argv[]){    if (argc > 1) {	initMC();	testas(argv[1]);    }else {      printf("Usage: myvm sourceFile\n");    }}#endif				/* _NATIVE */

⌨️ 快捷键说明

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