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

📄 isa.c

📁 深入理解计算机系统 的lab
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>#include <ctype.h>#include <stdio.h>#include <string.h>#include "isa.h"/* Are we running in GUI mode? */extern int gui_mode;/* Bytes Per Line = Block size of memory */#define BPL 32struct {    char *name;    int id;} reg_table[REG_NONE+1] = {    {"%eax",   REG_EAX},    {"%ecx",   REG_ECX},    {"%edx",   REG_EDX},    {"%ebx",   REG_EBX},    {"%esp",   REG_ESP},    {"%ebp",   REG_EBP},    {"%esi",   REG_ESI},    {"%edi",   REG_EDI},    {"----",  REG_NONE}};reg_id_t find_register(char *name){    int i;    for (i = 0; i < REG_NONE; i++)	if (!strcmp(name, reg_table[i].name))	    return reg_table[i].id;    return REG_NONE;}char *reg_name(reg_id_t id){    if (id < REG_NONE)	return reg_table[id].name;    else	return reg_table[REG_NONE].name;}instr_t instruction_set[] = {    {"nop",    HPACK(I_NOP, 0), 1, NO_ARG, 0, 0, NO_ARG, 0, 0 },    {"halt",   HPACK(I_HALT, 0), 1, NO_ARG, 0, 0, NO_ARG, 0, 0 },    {"rrmovl", HPACK(I_RRMOVL, 0), 2, R_ARG, 1, 1, R_ARG, 1, 0 },    /* arg1hi indicates number of bytes */    {"irmovl", HPACK(I_IRMOVL, 0), 6, I_ARG, 2, 4, R_ARG, 1, 0 },    {"rmmovl", HPACK(I_RMMOVL, 0), 6, R_ARG, 1, 1, M_ARG, 1, 0 },    {"mrmovl", HPACK(I_MRMOVL, 0), 6, M_ARG, 1, 0, R_ARG, 1, 1 },    {"addl",   HPACK(I_ALU, A_ADD), 2, R_ARG, 1, 1, R_ARG, 1, 0 },    {"subl",   HPACK(I_ALU, A_SUB), 2, R_ARG, 1, 1, R_ARG, 1, 0 },    {"andl",   HPACK(I_ALU, A_AND), 2, R_ARG, 1, 1, R_ARG, 1, 0 },    {"xorl",   HPACK(I_ALU, A_XOR), 2, R_ARG, 1, 1, R_ARG, 1, 0 },    /* arg1hi indicates number of bytes */    {"jmp",    HPACK(I_JMP, J_YES), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"jle",    HPACK(I_JMP, J_LE), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"jl",     HPACK(I_JMP, J_L), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"je",     HPACK(I_JMP, J_E), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"jne",    HPACK(I_JMP, J_NE), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"jge",    HPACK(I_JMP, J_GE), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"jg",     HPACK(I_JMP, J_G), 5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"call",   HPACK(I_CALL, 0),    5, I_ARG, 1, 4, NO_ARG, 0, 0 },    {"ret",    HPACK(I_RET, 0), 1, NO_ARG, 0, 0, NO_ARG, 0, 0 },    {"pushl",  HPACK(I_PUSHL, 0) , 2, R_ARG, 1, 1, NO_ARG, 0, 0 },    {"popl",   HPACK(I_POPL, 0) ,  2, R_ARG, 1, 1, NO_ARG, 0, 0 },    {"iaddl",  HPACK(I_IADDL, 0), 6, I_ARG, 2, 4, R_ARG, 1, 0 },    {"leave",  HPACK(I_LEAVE, 0), 1, NO_ARG, 0, 0, NO_ARG, 0, 0 },    /* this is just a hack to make the I_POP2 code have an associated name */    {"pop2",   HPACK(I_POP2, 0) , 0, NO_ARG, 0, 0, NO_ARG, 0, 0 },    /* For allocation instructions, arg1hi indicates number of bytes */    {".byte",  0x00, 1, I_ARG, 0, 1, NO_ARG, 0, 0 },    {".word",  0x00, 2, I_ARG, 0, 2, NO_ARG, 0, 0 },    {".long",  0x00, 4, I_ARG, 0, 4, NO_ARG, 0, 0 },    {NULL,     0   , 0, NO_ARG, 0, 0, NO_ARG, 0, 0 }};instr_t invalid_instr =    {"XXX",     0   , 0, NO_ARG, 0, 0, NO_ARG, 0, 0 };instr_ptr find_instr(char *name){    int i;    for (i = 0; instruction_set[i].name; i++)	if (strcmp(instruction_set[i].name,name) == 0)	    return &instruction_set[i];    return NULL;}/* Return name of instruction given its encoding */char *iname(int instr) {    int i;    for (i = 0; instruction_set[i].name; i++) {	if (instr == instruction_set[i].code)	    return instruction_set[i].name;    }    return "<bad>";}instr_ptr bad_instr(){    return &invalid_instr;}mem_t init_mem(int len){    mem_t result = (mem_t) malloc(sizeof(mem_rec));    len = ((len+BPL-1)/BPL)*BPL;    result->len = len;    result->contents = (byte_t *) calloc(len, 1);    return result;}void clear_mem(mem_t m){    memset(m->contents, 0, m->len);}void free_mem(mem_t m){    free((void *) m->contents);    free((void *) m);}mem_t copy_mem(mem_t oldm){    mem_t newm = init_mem(oldm->len);    memcpy(newm->contents, oldm->contents, oldm->len);    return newm;}bool_t diff_mem(mem_t oldm, mem_t newm, FILE *outfile){    word_t pos;    int len = oldm->len;    bool_t diff = FALSE;    if (newm->len < len)	len = newm->len;    for (pos = 0; (!diff || outfile) && pos < len; pos += 4) {	word_t ov, nv;	get_word_val(oldm, pos, &ov);	get_word_val(newm, pos, &nv);	if (nv != ov) {	    diff = TRUE;	    if (outfile)		fprintf(outfile, "0x%.4x:\t0x%.8x\t0x%.8x\n", pos, ov, nv);	}    }    return diff;}int hex2dig(char c){    if (isdigit((int)c))	return c - '0';    if (isupper((int)c))	return c - 'A' + 10;    else	return c - 'a' + 10;}#define LINELEN 4096int load_mem(mem_t m, FILE *infile, int report_error){    /* Read contents of .yo file */    char buf[LINELEN];    char c, ch, cl;    int byte_cnt = 0;    int lineno = 0;    word_t bytepos = 0;    int empty_line = 1;    int addr = 0;    char hexcode[15];#ifdef HAS_GUI    /* For display */    int line_no = 0;    char line[LINELEN];#endif /* HAS_GUI */       int index = 0;    while (fgets(buf, LINELEN, infile)) {	int cpos = 0;	empty_line = 1;	lineno++;	/* Skip white space */	while (isspace((int)buf[cpos]))	    cpos++;	if (buf[cpos] != '0' ||	    (buf[cpos+1] != 'x' && buf[cpos+1] != 'X'))	    continue; /* Skip this line */      	cpos+=2;	/* Get address */	bytepos = 0;	while (isxdigit((int)(c=buf[cpos]))) {	    cpos++;	    bytepos = bytepos*16 + hex2dig(c);	}	while (isspace((int)buf[cpos]))	    cpos++;	if (buf[cpos++] != ':') {	    if (report_error) {		fprintf(stderr, "Error reading file. Expected colon\n");		fprintf(stderr, "Line %d:%s\n", lineno, buf);		fprintf(stderr,			"Reading '%c' at position %d\n", buf[cpos], cpos);	    }	    return 0;	}	addr = bytepos;	while (isspace((int)buf[cpos]))	    cpos++;	index = 0;	/* Get code */	while (isxdigit((int)(ch=buf[cpos++])) && 	       isxdigit((int)(cl=buf[cpos++]))) {	    byte_t byte = 0;	    if (bytepos >= m->len) {		if (report_error) {		    fprintf(stderr,			    "Error reading file. Invalid address. 0x%x\n",			    bytepos);		    fprintf(stderr, "Line %d:%s\n", lineno, buf);		}		return 0;	    }	    byte = hex2dig(ch)*16+hex2dig(cl);	    m->contents[bytepos++] = byte;	    byte_cnt++;	    empty_line = 0;	    hexcode[index++] = ch;	    hexcode[index++] = cl;	}	/* Fill rest of hexcode with blanks */	for (; index < 12; index++)	    hexcode[index] = ' ';	hexcode[index] = '\0';#ifdef HAS_GUI	if (gui_mode) {	    /* Now get the rest of the line */	    while (isspace((int)buf[cpos]))		cpos++;	    cpos++; /* Skip over '|' */	    	    index = 0;	    while ((c = buf[cpos++]) != '\0' && c != '\n') {		line[index++] = c;	    }	    line[index] = '\0';	    if (!empty_line)		report_line(line_no++, addr, hexcode, line);	}#endif /* HAS_GUI */     }    return byte_cnt;}bool_t get_byte_val(mem_t m, word_t pos, byte_t *dest){    if (pos < 0 || pos >= m->len)	return FALSE;    *dest = m->contents[pos];    return TRUE;}bool_t get_word_val(mem_t m, word_t pos, word_t *dest){    int i;    word_t val;    if (pos < 0 || pos + 4 > m->len)	return FALSE;    val = 0;    for (i = 0; i < 4; i++)	val = val | m->contents[pos+i]<<(8*i);    *dest = val;    return TRUE;}bool_t set_byte_val(mem_t m, word_t pos, byte_t val){    if (pos < 0 || pos >= m->len)	return FALSE;    m->contents[pos] = val;    return TRUE;}bool_t set_word_val(mem_t m, word_t pos, word_t val){    int i;    if (pos < 0 || pos + 4 > m->len)	return FALSE;    for (i = 0; i < 4; i++) {	m->contents[pos+i] = val & 0xFF;	val >>= 8;    }    return TRUE;}void dump_memory(FILE *outfile, mem_t m, word_t pos, int len){    int i, j;    while (pos % BPL) {	pos --;	len ++;    }    len = ((len+BPL-1)/BPL)*BPL;    if (pos+len > m->len)	len = m->len-pos;    for (i = 0; i < len; i+=BPL) {	word_t val = 0;	fprintf(outfile, "0x%.4x:", pos+i);	for (j = 0; j < BPL; j+= 4) {	    get_word_val(m, pos+i+j, &val);	    fprintf(outfile, " %.8x", val);	}    }}mem_t init_reg(){    return init_mem(32);}void free_reg(mem_t r){    free_mem(r);}mem_t copy_reg(mem_t oldr){    return copy_mem(oldr);}bool_t diff_reg(mem_t oldr, mem_t newr, FILE *outfile){    word_t pos;    int len = oldr->len;    bool_t diff = FALSE;    if (newr->len < len)	len = newr->len;    for (pos = 0; (!diff || outfile) && pos < len; pos += 4) {	word_t ov, nv;	get_word_val(oldr, pos, &ov);	get_word_val(newr, pos, &nv);	if (nv != ov) {	    diff = TRUE;	    if (outfile)		fprintf(outfile, "%s:\t0x%.8x\t0x%.8x\n",			reg_table[pos/4].name, ov, nv);	}    }    return diff;}word_t get_reg_val(mem_t r, reg_id_t id){    word_t val;    if (id >= REG_NONE)	return 0;    get_word_val(r,id*4, &val);    return val;}void set_reg_val(mem_t r, reg_id_t id, word_t val){    if (id < REG_NONE) {	set_word_val(r,id*4,val);#ifdef HAS_GUI	if (gui_mode) {	    signal_register_update(id, val);	}#endif /* HAS_GUI */    }}     void dump_reg(FILE *outfile, mem_t r) {    reg_id_t id;    for (id = 0; id < 8; id++) {	fprintf(outfile, "   %s  ", reg_table[id].name);    }    fprintf(outfile, "\n");    for (id = 0; id < 8; id++) {	word_t val;	get_word_val(r, id*4, &val);	fprintf(outfile, " %x", val);    }    fprintf(outfile, "\n");}struct {    char symbol;    int id;} alu_table[A_NONE+1] = {    {'+',   A_ADD},    {'-',   A_SUB},    {'^',   A_XOR},    {'&',   A_AND},    {'?',   A_NONE}};char op_name(alu_t op){    if (op < A_NONE)	return alu_table[op].symbol;    else	return alu_table[A_NONE].symbol;}word_t compute_alu(alu_t op, word_t argA, word_t argB){    word_t val;    switch(op) {    case A_ADD:	val = argA+argB;	break;    case A_SUB:	val = argB-argA;	break;    case A_AND:	val = argA&argB;	break;    case A_XOR:	val = argA^argB;	break;    default:	val = 0;    }    return val;}cc_t compute_cc(alu_t op, word_t argA, word_t argB){    word_t val = compute_alu(op, argA, argB);    bool_t zero = (val == 0);    bool_t sign = ((int)val < 0);    bool_t ovf;    switch(op) {    case A_ADD:	ovf = ((int)argA < 0 == (int)argB < 0) &&	    ((int)val < 0 != (int)argA < 0);	break;    case A_SUB:

⌨️ 快捷键说明

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