Робота з симулятором машини Ноймана. Дослідження архітектури системи команд

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Інститут комп’ютерної техніки, автоматики та метрології
Факультет:
Не вказано
Кафедра:
Не вказано

Інформація про роботу

Рік:
2012
Тип роботи:
Звіт
Предмет:
Архітектура комп'ютерів

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА» ІНСТИТУТ КОМП’ЮТЕРНОЇ ТЕХНІКИ АВТОМАТИКИ ТА МЕТРОЛОГІЇ ЗВІТ ЛАБОРАТОРНОЇ РОБОТИ №4 З ПРЕДМЕТУ: «Архітектура комп’ютерів» ТЕМА: «Робота з симулятором машини Ноймана. Дослідження архітектури системи команд» Львів – 2012 Мета роботи: зрозуміти принципи виконання архітектури системи команд на симуляторі машини Ноймана, зрозуміти і дослідити виконання інструкції. Завдання: розширити архітектуру систему команд симулятора машини Ноймана, скласти програму на асемблері з розшириним набором команд, перетворити її у машинні коди, запустити симулятор, увести до нього коди машинних, проаналізувати і пояснити отримані результати, довести коректність роботи розширеного набору команд, скласти звіт з виконання лабораторних досліджень та захистити його. Хід роботи: Варіант 18 Побітове логічне І Лістинг програм: asol.c /* Assembler for LC */ #include <stdlib.h> #include <stdio.h> #include <string.h> #define MAXLINELENGTH 1000 #define MAXNUMLABELS 65536 #define MAXLABELLENGTH 7 /* includes the null character termination */ #define ADD 0 #define NAND 1 #define LW 2 #define SW 3 #define BEQ 4 #define JALR 5 #define HALT 6 #define AND 7 int readAndParse(FILE *, char *, char *, char *, char *, char *); int translateSymbol(char labelArray[MAXNUMLABELS][MAXLABELLENGTH], int labelAddress[MAXNUMLABELS], int, char *); int isNumber(char *); void testRegArg(char *); void testAddrArg(char *); int main(int argc, char *argv[]) { char *inFileString, *outFileString; FILE *inFilePtr, *outFilePtr; int address; char label[MAXLINELENGTH], opcode[MAXLINELENGTH], arg0[MAXLINELENGTH], arg1[MAXLINELENGTH], arg2[MAXLINELENGTH], argTmp[MAXLINELENGTH]; int i; int numLabels=0; int num; int addressField; char labelArray[MAXNUMLABELS][MAXLABELLENGTH]; int labelAddress[MAXNUMLABELS]; if (argc != 3) { printf("error: usage: %s <assembly-code-file> <machine-code-file>\n", argv[0]); exit(1); } inFileString = argv[1]; outFileString = argv[2]; inFilePtr = fopen(inFileString, "r"); if (inFilePtr == NULL) { printf("error in opening %s\n", inFileString); exit(1); } outFilePtr = fopen(outFileString, "w"); if (outFilePtr == NULL) { printf("error in opening %s\n", outFileString); exit(1); } /* map symbols to addresses */ /* assume address start at 0 */ for (address=0; readAndParse(inFilePtr, label, opcode, arg0, arg1, arg2); address++) { /* printf("%d: label=%s, opcode=%s, arg0=%s, arg1=%s, arg2=%s\n", address, label, opcode, arg0, arg1, arg2); */ /* check for illegal opcode */ if (strcmp(opcode, "add") && strcmp(opcode, "nand") && strcmp(opcode, "lw") && strcmp(opcode, "sw") && strcmp(opcode, "beq") && strcmp(opcode, "jalr") && strcmp(opcode, "halt") && strcmp(opcode, "and") && strcmp(opcode, ".fill") ) { printf("error: unrecognized opcode %s at address %d\n", opcode, address); exit(1); } /* check register fields */ if (!strcmp(opcode, "add") || !strcmp(opcode, "nand") || !strcmp(opcode, "lw") || !strcmp(opcode, "sw") || !strcmp(opcode, "and") || !strcmp(opcode, "beq") || !strcmp(opcode, "jalr")) { testRegArg(arg0); testRegArg(arg1); } if (!strcmp(opcode, "add") || !strcmp(opcode, "nand") || !strcmp(opcode, "and") ) { testRegArg(arg2); } /* check addressField */ if (!strcmp(opcode, "lw") || !strcmp(opcode, "sw") || !strcmp(opcode, "beq")) { testAddrArg(arg2); } if (!strcmp(opcode, ".fill")) { testAddrArg(arg0); } /* check for enough arguments */ if ( (strcmp(opcode, "halt") && strcmp(opcode, "and") && strcmp(opcode, ".fill") && strcmp(opcode, "jalr") && arg2[0]=='\0') || (!strcmp(opcode, "jalr") && arg1[0]=='\0') || (!strcmp(opcode, ".fill") && arg0[0]=='\0')) { printf("error at address %d: not enough arguments\n", address); exit(2); } if (label[0] != '\0') { /* check for labels that are too long */ if (strlen(label) >= MAXLABELLENGTH) { printf("label too long\n"); exit(2); } /* make sure label starts with letter */ if (! sscanf(label, "%[a-zA-Z]", argTmp) ) { printf("label doesn't start with letter\n"); exit(2); } /* make sure label consists of only letters and numbers */ sscanf(label, "%[a-zA-Z0-9]", argTmp); if (strcmp(argTmp, label)) { printf("label has character other than letters and numbers\n"); exit(2); } /* look for duplicate label */ for (i=0; i<numLabels; i++) { if (!strcmp(label, labelArray[i])) { printf("error: duplicate label %s at address %d\n", label, address); exit(1); } } /* see if there are too many labels */ if (numLabels >= MAXNUMLABELS) { printf("error: too many labels (label=%s)\n", label); exit(2); } strcpy(labelArray[numLabels], label); labelAddress[numLabels++] = address; } } for (i=0; i<numLabels; i++) { /* printf("%s = %d\n", labelArray[i], labelAddress[i]); */ } /* now do second pass (print machine code, with symbols filled in as addresses) */ rewind(inFilePtr); for (address=0; readAndParse(inFilePtr, label, opcode, arg0, arg1, arg2); address++) { if (!strcmp(opcode, "add")) { num = (ADD << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16) | atoi(arg2); } else if (!strcmp(opcode, "nand")) { num = (NAND << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16) | atoi(arg2); } else if (!strcmp(opcode, "jalr")) { num = (JALR << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16); } else if (!strcmp(opcode, "halt")) { num = (HALT << 22); } else if (!strcmp(opcode, "and")) { num = (AND << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16) | atoi(arg2); } else if (!strcmp(opcode, "lw") || !strcmp(opcode, "sw") || !strcmp(opcode, "beq")) { /* if arg2 is symbolic, then translate into an address */ if (!isNumber(arg2)) { addressField = translateSymbol(labelArray, labelAddress, numLabels, arg2); /* printf("%s being translated into %d\n", arg2, addressField); */ if (!strcmp(opcode, "beq")) { addressField = addressField-address-1; } } else { addressField = atoi(arg2); } if (addressField < -32768 || addressField > 32767) { printf("error: offset %d out of range\n", addressField); exit(1); } /* truncate the offset field, in case it's negative */ addressField = addressField & 0xFFFF; if (!strcmp(opcode, "beq")) { num = (BEQ << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16) | addressField; } else { /* lw or sw */ if (!strcmp(opcode, "lw")) { num = (LW << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16) | addressField; } else { num = (SW << 22) | (atoi(arg0) << 19) | (atoi(arg1) << 16) | addressField; } } } else if (!strcmp(opcode, ".fill")) { if (!isNumber(arg0)) { num = translateSymbol(labelArray, labelAddress, numLabels, arg0); } else { num = atoi(arg0); } } /* printf("(address %d): %d (hex 0x%x)\n", address, num, num); */ fprintf(outFilePtr, "%d\n", num); } exit(0); } /* * Read and parse a line of the assembly-language file. Fields are returned * in label, opcode, arg0, arg1, arg2 (these strings must have memory already * allocated to them). * * Return values: * 0 if reached end of file * 1 if all went well * * exit(1) if line is too long. */ int readAndParse(FILE *inFilePtr, char *label, char *opcode, char *arg0, char *arg1, char *arg2) { char line[MAXLINELENGTH]; char *ptr = line; /* delete prior values */ label[0] = opcode[0] = arg0[0] = arg1[0] = arg2[0] = '\0'; /* read the line from the assembly-language file */ if (fgets(line, MAXLINELENGTH, inFilePtr) == NULL) { /* reached end of file */ return(0); } /* check for line too long */ if (strlen(line) == MAXLINELENGTH-1) { printf("error: line too long\n"); exit(1); } /* is there a label? */ ptr = line; if (sscanf(ptr, "%[^\t\n ]", label)) { /* successfully read label; advance pointer over the label */ ptr += strlen(label); } /* * Parse the rest of the line. Would be nice to have real regular * expressions, but scanf will suffice. */ sscanf(ptr, "%*[\t\n\r ]%[^\t\n\r ]%*[\t\n\r ]%[^\t\n\r ]%*[\t\n\r ]%[^\t\n\r ]%*[\t\n\r ]%[^\t\n\r ]", opcode, arg0, arg1, arg2); return(1); } int translateSymbol(char labelArray[MAXNUMLABELS][MAXLABELLENGTH], int labelAddress[MAXNUMLABELS], int numLabels, char *symbol) { int i; /* search through address label table */ for (i=0; i<numLabels && strcmp(symbol, labelArray[i]); i++) { } if (i>=numLabels) { printf("error: missing label %s\n", symbol); exit(1); } return(labelAddress[i]); } int isNumber(char *string) { /* return 1 if string is a number */ int i; return( (sscanf(string, "%d", &i)) == 1); } /* * Test register argument; make sure it's in range and has no bad characters. */ void testRegArg(char *arg) { int num; char c; if (atoi(arg) < 0 || atoi(arg) > 7) { printf("error: register out of range\n"); exit(2); } if (sscanf(arg, "%d%c", &num, &c) != 1) { printf("bad character in register argument\n"); exit(2); } } /* * Test addressField argument. */ void testAddrArg(char *arg) { int num; char c; /* test numeric addressField */ if (isNumber(arg)) { if (sscanf(arg, "%d%c", &num, &c) != 1) { printf("bad character in addressField\n"); exit(2); } } } ssol.c /* * Instruction-level simulator for the LC */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUMMEMORY 65536 /* maximum number of words in memory */ #define NUMREGS 8 /* number of machine registers */ #define MAXLINELENGTH 1000 #define ADD 0 #define NAND 1 #define LW 2 #define SW 3 #define BEQ 4 #define JALR 5 #define HALT 6 #define AND 7 typedef struct stateStruct { int pc; int mem[NUMMEMORY]; int reg[NUMREGS]; int numMemory; } stateType; void printState(stateType *); void run(stateType); int convertNum(int); int main(int argc, char *argv[]) { int i; char line[MAXLINELENGTH]; stateType state; FILE *filePtr; if (argc != 2) { printf("error: usage: %s <machine-code file>\n", argv[0]); exit(1); } /* initialize memories and registers */ for (i=0; i<NUMMEMORY; i++) { state.mem[i] = 0; } for (i=0; i<NUMREGS; i++) { state.reg[i] = 0; } state.pc=0; /* read machine-code file into instruction/data memory (starting at address 0) */ filePtr = fopen(argv[1], "r"); if (filePtr == NULL) { printf("error: can't open file %s\n", argv[1]); perror("fopen"); exit(1); } for (state.numMemory=0; fgets(line, MAXLINELENGTH, filePtr) != NULL; state.numMemory++) { if (state.numMemory >= NUMMEMORY) { printf("exceeded memory size\n"); exit(1); } if (sscanf(line, "%d", state.mem+state.numMemory) != 1) { printf("error in reading address %d\n", state.numMemory); exit(1); } printf("memory[%d]=%d\n", state.numMemory, state.mem[state.numMemory]); } printf("\n"); /* run never returns */ run(state); return(0); } void run(stateType state) { int arg0, arg1, arg2, addressField; int instructions=0; int opcode; int maxMem=-1; /* highest memory address touched during run */ for (; 1; instructions++) { /* infinite loop, exits when it executes halt */ printState(&state); if (state.pc < 0 || state.pc >= NUMMEMORY) { printf("pc went out of the memory range\n"); exit(1); } maxMem = (state.pc > maxMem)?state.pc:maxMem; /* this is to make the following code easier to read */ opcode = state.mem[state.pc] >> 22; arg0 = (state.mem[state.pc] >> 19) & 0x7; arg1 = (state.mem[state.pc] >> 16) & 0x7; arg2 = state.mem[state.pc] & 0x7; /* only for add, nand */ addressField = convertNum(state.mem[state.pc] & 0xFFFF); /* for beq, lw, sw */ state.pc++; if (opcode == ADD) { state.reg[arg2] = state.reg[arg0] + state.reg[arg1]; } else if (opcode == NAND) { state.reg[arg2] = ~(state.reg[arg0] & state.reg[arg1]); } else if (opcode == LW) { if (state.reg[arg0] + addressField < 0 || state.reg[arg0] + addressField >= NUMMEMORY) { printf("address out of bounds\n"); exit(1); } state.reg[arg1] = state.mem[state.reg[arg0] + addressField]; if (state.reg[arg0] + addressField > maxMem) { maxMem = state.reg[arg0] + addressField; } } else if (opcode == SW) { if (state.reg[arg0] + addressField < 0 || state.reg[arg0] + addressField >= NUMMEMORY) { printf("address out of bounds\n"); exit(1); } state.mem[state.reg[arg0] + addressField] = state.reg[arg1]; if (state.reg[arg0] + addressField > maxMem) { maxMem = state.reg[arg0] + addressField; } } else if (opcode == BEQ) { if (state.reg[arg0] == state.reg[arg1]) { state.pc += addressField; } } else if (opcode == JALR) { state.reg[arg1] = state.pc; if(arg0 != 0) state.pc = state.reg[arg0]; else state.pc = 0; } //////////////////////////////////////////// else if (opcode == AND) { state.reg[arg2] = (state.reg[arg0] & state.reg[arg1]); } //////////////////////////////////////////// else if (opcode == HALT) { printf("machine halted\n"); printf("total of %d instructions executed\n", instructions+1); printf("final state of machine:\n"); printState(&state); exit(0); } else { printf("error: illegal opcode 0x%x\n", opcode); exit(1); } state.reg[0] = 0; } } void printState(stateType *statePtr) { int i; printf("\n@@@\nstate:\n"); printf("\tpc %d\n", statePtr->pc); printf("\tmemory:\n"); for (i=0; i<statePtr->numMemory; i++) { printf("\t\tmem[ %d ] %d\n", i, statePtr->mem[i]); } printf("\tregisters:\n"); for (i=0; i<NUMREGS; i++) { printf("\t\treg[ %d ] %d\n", i, statePtr->reg[i]); } printf("end state\n"); } int convertNum(int num) { /* convert a 16-bit number into a 32-bit Sun integer */ if (num & (1<<15) ) { num -= (1<<16); } return(num); } Зміст файлу 1.as: start lw 0 1 var1 lw 0 2 var2 and 1 2 3 halt var1 .fill 6 var2 .fill 3 stAddr .fill start Зміст файлу 1.mc: 8454148 8519685 30015491 25165824 6 3 2 Файл report.txt memory[0]=8454148 memory[1]=8519685 memory[2]=30015491 memory[3]=25165824 memory[4]=6 memory[5]=3 memory[6]=2 @@@ state: pc 0 memory: mem[ 0 ] 8454148 mem[ 1 ] 8519685 mem[ 2 ] 30015491 mem[ 3 ] 25165824 mem[ 4 ] 6 mem[ 5 ] 3 mem[ 6 ] 2 registers: reg[ 0 ] 0 reg[ 1 ] 0 reg[ 2 ] 0 reg[ 3 ] 0 reg[ 4 ] 0 reg[ 5 ] 0 reg[ 6 ] 0 reg[ 7 ] 0 end state @@@ state: pc 1 memory: mem[ 0 ] 8454148 mem[ 1 ] 8519685 mem[ 2 ] 30015491 mem[ 3 ] 25165824 mem[ 4 ] 6 mem[ 5 ] 3 mem[ 6 ] 2 registers: reg[ 0 ] 0 reg[ 1 ] 6 reg[ 2 ] 0 reg[ 3 ] 0 reg[ 4 ] 0 reg[ 5 ] 0 reg[ 6 ] 0 reg[ 7 ] 0 end state @@@ state: pc 2 memory: mem[ 0 ] 8454148 mem[ 1 ] 8519685 mem[ 2 ] 30015491 mem[ 3 ] 25165824 mem[ 4 ] 6 mem[ 5 ] 3 mem[ 6 ] 2 registers: reg[ 0 ] 0 reg[ 1 ] 6 reg[ 2 ] 3 reg[ 3 ] 0 reg[ 4 ] 0 reg[ 5 ] 0 reg[ 6 ] 0 reg[ 7 ] 0 end state @@@ state: pc 3 memory: mem[ 0 ] 8454148 mem[ 1 ] 8519685 mem[ 2 ] 30015491 mem[ 3 ] 25165824 mem[ 4 ] 6 mem[ 5 ] 3 mem[ 6 ] 2 registers: reg[ 0 ] 0 reg[ 1 ] 6 reg[ 2 ] 3 reg[ 3 ] 2 reg[ 4 ] 0 reg[ 5 ] 0 reg[ 6 ] 0 reg[ 7 ] 0 end state machine halted total of 4 instructions executed final state of machine: @@@ state: pc 4 memory: mem[ 0 ] 8454148 mem[ 1 ] 8519685 mem[ 2 ] 30015491 mem[ 3 ] 25165824 mem[ 4 ] 6 mem[ 5 ] 3 mem[ 6 ] 2 registers: reg[ 0 ] 0 reg[ 1 ] 6 reg[ 2 ] 3 reg[ 3 ] 2 reg[ 4 ] 0 reg[ 5 ] 0 reg[ 6 ] 0 reg[ 7 ] 0 end state Висновок: виконавши дану лабораторну роботу, я зрозуміла принципи виконання архітектури системи команд на симуляторі машини Ноймана, зрозуміла і дослідила виконання інструкції.
Антиботан аватар за замовчуванням

21.10.2013 21:10-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!