c语言写cpu

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned char ram[0x1000];
//采用小端序
//内存32kb,char型1个byte,8个bit
                //0-16383 为代码段
                //16384-32767 为数据段
//memset(ram, 0, sizeof(ram));

short ip = 0; //ip16位可以c寻址32k内存空间

unsigned int ir = 0; //指令寄存器

int flag = 0;

//8个16位寄存器组
short ax[8] = {0};
/*short ax2 = 0;
short ax3 = 0;
short ax4 = 0;
short ax5 = 0;
short ax6 = 0;
short ax7 = 0;
short ax8 = 0;*/

void reset() {
    ip = 0;
    ir = 0;
    flag = 0;
    memset(ax, 0, 8);
    memset(ram, 0, 0x1000);
}

//显示内存状态
void show_cpu_state() {
    printf("ip = %d\n", ip);
    printf("flag = %d\n", flag);
    printf("ir = %08x\n", ir);
    
    printf("ax1 = %d ax2 = %d ax3 = %d ax4 = %d\n", ax[0], ax[1], ax[2], ax[3]);
    printf("ax5 = %d ax6 = %d ax7 = %d ax8 = %d\n", ax[4], ax[5], ax[6], ax[7]);
}

//显示内存数据段与代码段状态
void show_ram_state() {
    int i = 0;
    printf("CodeSegment:");
    for(;i < 64; i++) {
        if(i % 4 == 0)
            printf("\n");
        printf("%02x ", ram[i]);
    }
    printf("\nDataSegment:");
    for(i = 16384; i < 16896; i+=2) {
        int n = 0;
        n += ram[i+1];
        n = n << 8;
        n += ram[i];
        if(i % 32 == 0)
            printf("\n");
        printf("%d ", n);
    }
    printf("\n");
}

//char指令转正2进制形式存储
void str2binary(int index, char instruction[]) {
    int i = index;
    int j = 0;
    for(; j < 4; ++j) {
        int k = j*8;
        char temp[9];
        strncpy(temp, instruction + k, 8);
        //printf("%s Hex:", temp);
        unsigned char n = 0;
        unsigned char t = 0;
        int p = 0;
        int q = 0x80;
        for(; p < 8; ++p) {
            temp[p] -= 0x30;
            t = temp[p] * q;
            q = q >> 1;
            n += t;
        }
        /*temp[0] -= 0x30;
        t = temp[0] * 0x80;
        n += t;
        
        temp[1] -= 0x30;
        t = temp[1] * 0x40;
        n += t;
        
        temp[2] -= 0x30;
        t = temp[2] * 0x20;
        n += t;
        
        temp[3] -= 0x30;
        t = temp[3] * 0x10;
        n += t;
        
        temp[4] -= 0x30;
        t = temp[4] * 0x08;
        n += t;
        
        temp[5] -= 0x30;
        t = temp[5] * 0x04;
        n += t;
        
        temp[6] -= 0x30;
        t = temp[6] * 0x02;
        n += t;
        
        temp[7] -= 0x30;
        t = temp[7] * 0x01;
        n += t;*/
        ram[i] = n;
        //printf("%02x\n", ram[i]);
        ++i;
    }
}

//函数功能:将文件中的指令读入内存的代码段
//输入:文件地址
//输出:无
void instructions_loading(char* fileAddr) {
    FILE *fp;
    fp=fopen(fileAddr,"r");
    char instruction[33],ch[5];
    int i=0;
    while(fgets(instruction,33,fp) != NULL){
        //printf("%s\n", instruction);
        str2binary(4*i, instruction);
        
        fgets(ch, 5, fp);
        //printf("%c", ch);
        i++;
    }
    //printf("%d", i);
    //countl=i;
    fclose(fp);
    return;
}




//函数功能:将代码段中ip指向的指令取出,装入指令寄存器ir
//输入:全局的ip和ram
//输出:无
void load_instruction() {
    ir = 0;
    ir += ram[ip];
    ir = ir << 8;
    ir += ram[ip+1];
    ir = ir << 8;
    ir += ram[ip+2];
    ir = ir << 8;
    ir += ram[ip+3];
    //show_cpu_state();
}

//函数功能:ip指向内存中下一条将要执行的地址
//输入:全局 ip
//输出:无
void inc_ip() {
    ip += 4;
}

//函数功能:分析指令
//输入:ir中的指令
//输出:控制信号
int decode() {
    unsigned int opcode = ir;
    opcode = opcode >> 24;
    switch(opcode) {
        case 0:  return 0;
        case 1:  return 1;
        case 2:  return 2;
        case 3:  return 3;
        case 4:  return 4;
        case 5:  return 5;
        case 6:  return 6;
        case 7:  return 7;
        case 8:  return 8;
        case 9:  return 9;
        case 10:  return 10;
        case 11:  return 11;
        case 12:  return 12;
    }
    return 13;
}

void input(unsigned int func) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    //printf("%d", front-1);
    
    printf("in:\n");
    //setbuf(stdin, NULL);
    
    //printf("%c\n", ch);
    short in;
    //setbuf(stdin, NULL);
    //char ch;
    //scanf("%c", &ch);
    scanf("%hd", &in);
    getchar();
    ax[front-1] = in;
}

void output(unsigned int func) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    
    printf("out:%hd\n", ax[front-1]);
}




void mov(unsigned int func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        printf("front = %d\n", front-1);
        ax[front-1] = imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        ax[front-1] = 0;
        ax[front-1] |= ram[ax[rear-1]+1];
        ax[front-1] = ax[front-1] << 8;
        ax[front-1] |= ram[ax[rear-1]];
    }
    else { // 前内存,后寄存器
        ram[ax[front-1]] = (char)ax[rear-1];
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        short temp = ax[rear-1];
        temp = temp >> 8;
        ram[ax[front-1]+1] = (char)temp;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
}

void add(unsigned int func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] += imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        ax[front-1] += t;
    }
    else { // 前内存,后寄存器
        short t2 = 0;
        t2 |= ram[ax[rear-1]+1];
        t2 = ax[front-1] << 8;
        t2 |= ram[ax[rear-1]];
        t2 += ax[rear-1];
        ram[ax[front-1]] = (char)t2;
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        t2 = t2 >> 8;
        ram[ax[front-1]+1] = (char)t2;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
    
}

void sub(unsigned short func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] -= imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        
        ax[front-1] -= t;
    }
    else { // 前内存,后寄存器
        short t2 = 0;
        t2 |= ram[ax[rear-1]+1];
        t2 = ax[front-1] << 8;
        t2 |= ram[ax[rear-1]];
        
        t2 -= ax[rear-1];
        
        ram[ax[front-1]] = (char)t2;
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        t2 = t2 >> 8;
        ram[ax[front-1]+1] = (char)t2;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
}

void mul(unsigned short func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] *= imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        
        ax[front-1] *= t;
    }
    else { // 前内存,后寄存器
        short t2 = 0;
        t2 |= ram[ax[rear-1]+1];
        t2 = ax[front-1] << 8;
        t2 |= ram[ax[rear-1]];
        
        t2 *= ax[rear-1];
        
        ram[ax[front-1]] = (char)t2;
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        t2 = t2 >> 8;
        ram[ax[front-1]+1] = (char)t2;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
}

void mydiv(unsigned short func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] /= imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        
        ax[front-1] /= t;
    }
    else { // 前内存,后寄存器
        short t2 = 0;
        t2 |= ram[ax[rear-1]+1];
        t2 = ax[front-1] << 8;
        t2 |= ram[ax[rear-1]];
        
        t2 /= ax[rear-1];
        
        ram[ax[front-1]] = (char)t2;
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        t2 = t2 >> 8;
        ram[ax[front-1]+1] = (char)t2;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
}

void and(unsigned short func, short imm) {
    unsigned char temp = (unsigned char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] &= imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        
        ax[front-1] &= t;
    }
    else { // 前内存,后寄存器
        short t2 = 0;
        t2 |= ram[ax[rear-1]+1];
        t2 = ax[front-1] << 8;
        t2 |= ram[ax[rear-1]];
        
        t2 &= ax[rear-1];
        
        ram[ax[front-1]] = (char)t2;
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        t2 = t2 >> 8;
        ram[ax[front-1]+1] = (char)t2;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
}

void or(unsigned short func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] |= imm;
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        
        ax[front-1] |= t;
    }
    else { // 前内存,后寄存器
        short t2 = 0;
        t2 |= ram[ax[rear-1]+1];
        t2 = ax[front-1] << 8;
        t2 |= ram[ax[rear-1]];
        
        t2 |= ax[rear-1];
        
        ram[ax[front-1]] = (char)t2;
        //printf("Mov1:%d\n", ram[ax[front-1]]);
        t2 = t2 >> 8;
        ram[ax[front-1]+1] = (char)t2;
        //printf("Mov2:%d\n", ram[ax[front-1]+1]);
    }
}

void not(unsigned short func) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    if(rear == 0) {
        ax[front-1] = !!(~ax[front-1]);
    }
    else if(rear >= (char)5) { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        t = ax[front-1] << 8;
        t |= ram[ax[rear-1]];
        
        t = ~t;
        ram[ax[rear-1]] = (char)t;
        t = t >> 8;
        ram[ax[rear-1]+1] = (char)t;
    }
    else {
        printf("error!");
        exit(1);
    }
}

void cmp(unsigned short func, short imm) {
    unsigned char temp = (char)func;
    char front = temp >> 4;
    char rear = temp & 0x0f;
    printf("imm=%d\n", imm);
    if(rear == 0) {
        if(ax[front-1] > imm)
            flag = 1;
        else if(ax[front-1] == imm)
            flag = 0;
        else
            flag = -1;
    }
    else { // 前寄存器,后内存
        short t = 0;
        t |= ram[ax[rear-1]+1];
        //printf("1=%x\n",ram[ax[rear-1]+1]);
        t = t << 8;
        t |= ram[ax[rear-1]];
        //printf("2=%x\n", ram[ax[rear-1]]);
        //printf("t:%d\n", t);
        if(ax[front-1] > t)
            flag = 1;
        else if(ax[front-1] == t)
            flag = 0;
        else
            flag = -1;
    }
    
}

void jmp(unsigned short func, short imm) {
    imm -= 4;
    if(func == 0x00) {
        //printf("ip = %d\n", ip);
        ip += imm;
        //printf("imm = %d\n", imm);
    }
    else if(func == 0x01) {
        if(flag == 0)
            ip += imm;
    }
    else if(func == 0x02) {
        if(flag == 1)
            ip += imm;
    }
    else {
        if(flag == -1)
            ip += imm;
    }
}

void halt() {
    show_cpu_state();
    show_ram_state();
    exit(1);
}


//函数功能:执行指令
//输入:控制信号
//输出:
void execute_instrument(int ctrl) {
    unsigned int func = ir;
    //printf("func1=%02x\n", func);
    func = func >> 16;
    //printf("func1=%02x\n", func);
    func = func & 0x00ff;
    short imm = (short)ir;
    printf("func=%02x\n", func);
    switch(ctrl) {
        case 0: {
            //printf("finish!");
            halt();
        }
        case 1: {
            //printf("\nmov");
            mov(func, imm);
            break;
        }
        case 2: {
            //printf("\nadd");
            add(func, imm);
            break;
        }/*
        case 3: {
            printf("\nsub");
            sub(func);
            break;
        }
        case 4: {
            printf("\nmul");
            mul(func);
            break;
        }
        case 5: {
            printf("\ndiv");
            mydiv(func);
            break;
        }
        case 6: {
            printf("\nand");
            and(func);
            break;
        }
        case 7: {
            printf("\nor");
            or(func);
            break;
        }
        case 8: {
            printf("\nnot");
            not(func);
            break;
        }*/
        case 9: {
            //printf("\ncmp");
            cmp(func, imm);
            break;
        }
        case 10: {
            //printf("\njmp");
            jmp(func, imm);
            break;
        }
        case 11: {
            input(func);
            break;
        }
        case 12: {
            output(func);
            break;
        }
    }
}



//函数功能:

int main(int argc, char *argv[]) {
    reset();
    instructions_loading(argv[1]);
    printf("instructions_loading done!\n");
    
    //show_cpu_state();
    //show_ram_state();
    
    int i = 0;
    while(1) {
        i++;
        //printf("%d:\n", i);
        //if(i == 24) // jmp写完了,从jmp下一条开始
          //  break;
        load_instruction();
        
        inc_ip();
        //show_cpu_state();
    
        int ctrl = decode();
    printf("ctrl = %d\n", ctrl);
        
        execute_instrument(ctrl);
        show_cpu_state();
        show_ram_state();
    }
    //show_cpu_state();
    //show_ram_state();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值