Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Помогите решить C++ Ассемблер

Влад Иванов Ученик (93), на голосовании 5 месяцев назад
Задания связаны с проектированием ассемблеров. Исходными данными являются потоки ассемблерных команд и директив, записанные в соответствии с правилами языка Ассемблера. Результат обработки должен максимально совпадать с теми данными, которые формирует стандартный ассемблер (tasm, masm или ассемблер для ОС Linux). В текстах заданий для указания операндов используются следующие обозначения:
r – операнд находится в регистре общего назначения (РОН);
m – операнд находится в основной памяти;
imm – непосредственный операнд.
Для обозначения схемы построения транслятора применяются сокращения:
2А – двухпросмотровый ассемблер;
1А>ОП – однопросмотровый ассемблер с непосредственной записью результата в оперативную память с целью выполнения сформированного объектного кода сразу после завершения ассемблирования;
1А>МД – однопросмотровый ассемблер, записывающий формируемый объектный код на магнитный диск;
МА – многопромотровый ассемблер;
ДА – программа дизассемблер – восстановление текста программы по объектному коду.
Дополнительно в задании указана разрядность процессора:
16 – 16-разрядный процессор или реальный режим 32-разрядных процессоров i80х86;
32 – 32-разрядный процессор, работающий в защищенном режиме.
Для заданий типа “1А>ОП” требуется разместить результаты ассемблирования в области данных, затем загрузить РОНы эталонными значениями, передать управление на сформированный объектный код. После исполнения объектного кода требуется распечатать содержимое памяти и/или регистров для доказательства правильности выполненного задания.
Для заданий типа “1А>МД” требуется дополнительно разработать простой формат файла с объектным кодом, а также простую программу-загрузчик. Программа-загрузчик должна программу из файла перенести в оперативную память, произвести необходимую настройку адресов и запустить эту программу на выполнение.

Исходные данные содержат команды вида:

МНЕМА r,r
МНЕМА r,imm
МНЕМА r,name
МНЕМА name,r

ret
name1 dw 5

namek dw 5
end

Здесь МНЕМА = [add, sub, cmp]. Операнд в памяти (m) может быть задан одним из следующих способов: namei, namei[BX], namei[BX+SI] , namei[BX+DI].
Требуется сформировать листинг для этого потока команд для случая 32-разрядных операндов.


Пример другого варианта:
Требуется разработать ассемблер для формирования выполняемого файла .сом формата. Представить скриншоты проверочных запусков полученной программы под управлением отладчика (td.exe).
Исходные данные содержат команды вида:
МНЕМА r,constanta
МНЕМА r,CL
МНЕМА m,constanta
МНЕМА m,CL
Здесь МНЕМА = [shr, shl]. Операнд в памяти (m) может быть задан одним из следующих способов: [BX], [SI], [DI], [BX+SI], [BX+DI].
Описание
Рассмотрим алгоритм решения текущей задачи.
1)Чтение файла с программой на ассемблере.
2)Рассмотрение каждой строки, определение типа команды и операндов.
3)Расчет смещения для каждой метки.
4)Если в качестве операнда выступала та или иная метка, то следует сохранить ее адрес.
5)Сохранение непрерывной строки из кодов команд в файл .com формата, а также вывод ее на экран(для удобства).
Стоит отметить, что для формирования реального .com файла пришлось также написать обработку команд вида:
lea регистр1, непосредственный операнд
mov регистр, память
ret
Код не смог прикрепить, код должен быть на C++
Голосование за лучший ответ
Татьяна Просветленный (36384) 6 месяцев назад
 #include  
#include
#include
#include
#include
#include

using namespace std;

struct Instruction {
string mnemonic;
string operand1;
string operand2;
};

vector parseAssemblyFile(const string& filename) {
ifstream file(filename);
vector instructions;
string line;

while (getline(file, line)) {
istringstream iss(line);
Instruction inst;
iss >> inst.mnemonic >> inst.operand1 >> inst.operand2;
instructions.push_back(inst);
}

return instructions;
}

map calculateOffsets(const vector& instructions) {
map labelOffsets;
int offset = 0;

for (const auto& inst : instructions) {
if (inst.mnemonic == "name") {
labelOffsets[inst.operand1] = offset;
} else {
// Assuming fixed size for simplicity, usually it varies
offset += 2;
}
}

return labelOffsets;
}

void generateObjectCode(const vector& instructions, const map& labelOffsets, const string& outputFilename) {
ofstream outFile(outputFilename, ios::binary);

for (const auto& inst : instructions) {
if (inst.mnemonic == "name") continue;

if (inst.mnemonic == "add") {
outFile.put(0x01); // Example opcode
} else if (inst.mnemonic == "sub") {
outFile.put(0x29); // Example opcode
} // Add other mnemonics similarly

if (inst.operand1[0] == 'r' && inst.operand2[0] == 'r') {
// Register to Register
outFile.put((char)stoi(inst.operand1.substr(1))); // Register code
outFile.put((char)stoi(inst.operand2.substr(1))); // Register code
} else if (inst.operand1[0] == 'r' && inst.operand2[0] == 'i') {
// Register to Immediate
outFile.put((char)stoi(inst.operand1.substr(1))); // Register code
int imm = stoi(inst.operand2.substr(1));
outFile.write((char*)&imm, sizeof(int));
} // Add other operand types similarly
}
}

void printObjectCode(const string& outputFilename) {
ifstream inFile(outputFilename, ios::binary);
char byte;

while (inFile.get(byte)) {
cout << hex << setw(2) << setfill('0') << (int)(unsigned char)byte << " ";
}
cout << endl;
}

int main() {
string inputFilename = "input.asm";
string outputFilename = "output.com";

vector instructions = parseAssemblyFile(inputFilename);
map labelOffsets = calculateOffsets(instructions);
generateObjectCode(instructions, labelOffsets, outputFilename);
printObjectCode(outputFilename);

return 0;
}
Dians Мастер (2017) 6 месяцев назад
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

//определение структуры для хранения меток и их адресов
struct Label {
std::string name;
int address;
};

//функция парсинга строки для получения команд и операндов
void parseLine(std::string line, std::string& command, std::vector<std::string>& operands) {
// ваша логика парсинга строки
}

//функция для чтения ассемблерной программы из файла
void readAssemblyFile(std::string filename, std::vector<std::string>& lines) {
std::ifstream file(filename);
if ( file.is _open()) {
std::string line;
while (std::getline(file, line)) {
lines.push_back(line);
}
file.close();
} else {
std::cout << "Unable to open file" << std::endl;
}
}

//функция для выделения меток и расчета их адресов
void processLabels(std::vector<std::string>& lines, std::map<std::string, int>& labelMap) {
// ваша логика обработки меток
}

//функция для формирования .com файла и вывода команд на экран
void generateComFile(std::vector<std::string>& lines, std::map<std::string, int>& labelMap) {
// ваша логика генерации .com файла
}

int main() {
std::vector<std::string> lines;
std::map<std::string, int> labelMap;

readAssemblyFile("input.asm", lines);
processLabels(lines, labelMap);
generateComFile(lines, labelMap);

return 0;
}

сделал ИИ ( ссылка )
Похожие вопросы