-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAssembler.h
More file actions
115 lines (95 loc) · 3.19 KB
/
Assembler.h
File metadata and controls
115 lines (95 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#pragma once
#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#include <string>
#include <vector>
#include <cstdint>
#include <sstream>
#include <algorithm>
#include <cctype>
#include "Memory.h"
#include "CU.h"
using namespace std;
class Assembler {
private:
CU cu;
// 문자열 trim
string trim(const string& str) {
size_t first = str.find_first_not_of(" \t\r\n");
if (first == string::npos) return "";
size_t last = str.find_last_not_of(" \t\r\n");
return str.substr(first, last - first + 1);
}
// 소문자->대문자로 변환
string toUpper(const string& str) {
string result = str;
transform(result.begin(), result.end(), result.begin(), ::toupper);
return result;
}
public:
Assembler() {}
// 어셈블리 코드를 16bit 기계어로 변환
// return : 성공시 true, 실패시 false
bool assembleLine(const string& line, uint16_t& result) {
string trimmed = trim(line);
if (trimmed.empty() || trimmed[0] == '#' || trimmed[0] == ';') {
return false;
}
// opcode와 operand 분리
stringstream ss(trimmed);
string opcode, operandStr;
ss >> opcode >> operandStr;
opcode = toUpper(opcode);
operandStr = toUpper(operandStr);
// opcode 변환
int opcodeValue = cu.stringToOpcode(opcode);
if (opcodeValue < 0) {
cerr << "[Assembler Error] Unknown opcode: " << opcode << endl;
return false;
}
// operand 변환
uint16_t operand = 0;
if (!operandStr.empty()) {
if (operandStr.substr(0, 2) == "0X") {
operandStr = operandStr.substr(2);
}
try {
operand = static_cast<uint16_t>(stoul(operandStr, nullptr, 16));
}
catch (...) {
cerr << "[Assembler Error] Invalid operand: " << operandStr << endl;
return false;
}
}
if (operand > 0x0FFF) {
cerr << "[Assembler Error] Operand exceeds 12 bits: " << operandStr << endl;
return false;
}
// 16bit 명령어 조합: opcode(4bit) | operand(12bit)
result = (static_cast<uint16_t>(opcodeValue) << 12) | operand;
return true;
}
// 여러 줄의 어셈블리를 메모리에 로드
// return : 로드된 명령어 수
int loadProgram(Memory* memory, const vector<string>& lines, unsigned int startAddr) {
int count = 0;
unsigned int currentAddr = startAddr;
for (const string& line : lines) {
uint16_t instruction;
if (assembleLine(line, instruction)) {
if (!memory->isValidAddress(currentAddr + 1)) {
cerr << "[Assembler Error] Memory address overflow" << endl;
break;
}
memory->write(currentAddr, instruction);
cout << " 0x" << hex << setw(3) << setfill('0') << currentAddr
<< ": " << trim(line) << " -> 0x"
<< setw(4) << setfill('0') << instruction << dec << endl;
currentAddr += 2; // 16bit = 2bytes
count++;
}
}
return count;
}
};
#endif