МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИНАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА»
ІНСТИТУТ КОМП’ЮТЕРНОЇ ТЕХНІКИ АВТОМАТИКИ ТА МЕТРОЛОГІЇ
«Архітектура комп’ютерів»
ЗВІТ ДО ЛАБОРАТОРНОЇ РОБОТИ №4 ТЕМА:
«Робота з симулятором машини Ноймана. Дослідження архітектури системи команд.»
Підготував: ст.гр КІ-35
Мацюк Т.І.
Прийняв: Клименко В.А.
Львів – 2012
Мета: зрозуміти принципи виконання архітектури системи команд на симуляторі машини Ноймана, зрозуміти і дослідити виконання інструкції.
Завдання: розширити архітектуру систему команд симулятора машини Ноймана, скласти програму на асемблері з розшириним набором команд, перетворити її у машинні коди, запустити симулятор, увести до нього коди машинних, проаналізувати і пояснити отримані результати, довести коректність роботи розширеного набору команд, скласти звіт з виконання лабораторних досліджень та захистити його.
Теоретичні відомості
Загальна схема роботи асемблера складається з 2 проходів. На першому проході асемблер перевіряє коректність синтаксису команд. На другому виконується генерування відповідних машинних команд, тобто числового представлення асемблерної команди.
Функція readAndParse виконує зчитування рядку асемблерної програми і декодування на відповідні поля: мітка, код операції, операнди. Отримана таким чином і декодована інструкція перевіряється на коректність: існування команди, відповідна кількість аргументів, існування міток та т. п.
Функція testRegArg перевіряє коректність використання назви регістра.
Функція testAddrArg перевіряє коректність використання адреси.
Функція labelArray перетворює відповідну мітку у адресу.
Program.as та program.mc – відповідно вхідний та вихідний файли.
Симулятор починає свою роботу ініціалізацією пам’яті та регістрів 0 значеннями (рис. 2.). Наступним кроком відбувається заванаження програми у машинних кодах в пам’ять. Далі відбувається покрокове виконання інструкцій та вивід стану на зовнішній пристрій (чи на екран консолі чи у файл).
У stateStruct зберігається стан машини – значення регістрів, пам’яті та програмний лічільник. stateStruct
Функція Run виконує обробку інструкцій з пам’яті, функція printState виводить поточний стан машини, а функція convertNum виконує перетворення числа у доповняльний код.
Хід виконання роботи:
1. Відкрити вихідні файли з вихідними кодами (assol.c ssol.c)
2. Відкомпілювати дані вихідні коди у окремих проектах.
3. Дослідити алгоритм роботи асемблерної та симуляційної програми.
4. Замінити інструкцію noop власною згідно індивідуального варіанту.
5. Перетворити асемблер ний код у машинний.
6. Запустити симулятор з отриманим у п.5 машинним кодом.
7. Проаналізувати хід виконання машинних інструкцій, перевірити правильність результатів.
8. Скласти звіт по результатам виконання програми.
Виконання лабораторної роботи
14
Інкремент
Фрагменти коду в які були внесені зміни в ході виконання роботи.
asol.c
/* 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, "INC")) {
num = (INC << 22) | (atoi(arg0) << 19);
} else if (!strcmp(opcode, "lw") || !strcmp(opcode, "sw") ||
!strcmp(opcode, "beq")) {
ssol.c
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 == INC) {
state.reg[arg1] = state.reg[arg0]+1;
} 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);
Лістінг тестової програми.
lw 0 1 var1
start inc 1
sw 0 1 5
done halt end of program
var1 .fill 15
stAddr .fill start will contain the address of start (2)
Результат роботи
memory[0]=8454148
memory[1]=29884416
memory[2]=12648453
memory[3]=25165824
memory[4]=15
memory[5]=1
@@@
state:
pc 0
memory:
mem[ 0 ] 8454148
mem[ 1 ] 29884416
mem[ 2 ] 12648453
mem[ 3 ] 25165824
mem[ 4 ] 15
mem[ 5 ] 1
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 4
memory:
mem[ 0 ] 8454148
mem[ 1 ] 29884416
mem[ 2 ] 12648453
mem[ 3 ] 25165824
mem[ 4 ] 15
mem[ 5 ] 16
registers:
reg[ 0 ] 0
reg[ 1 ] 16
reg[ 2 ] 0
reg[ 3 ] 0
reg[ 4 ] 0
reg[ 5 ] 0
reg[ 6 ] 0
reg[ 7 ] 0
end state
Висновок: На даній лабораторній роботі я зрозумів принципи виконання архітектури системи команд на симуляторі машини Ноймана, зрозумів і дослідив виконання інструкції.