Разработка и оптимизация программного обеспечения для УУМ-32

Концепция универсальной учебной машины УУМ-32. Требования к программным и аппаратным средствам. Реализация программного обеспечения. Описание приложения "Макроассемблер для УУМ-32". Стадии и этапы разработки. Функциональное назначение приложения.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 26.11.2014
Размер файла 1,5 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

private string GetAbsolutePathFromCurrent(string path) {

return PathFinder.GetAbsolutePath(this.selfExeFile, path);

}

private int StartCompilation() {

MDIForm activeChild = (MDIForm)this.ActiveMdiChild;

if (activeChild == null) {

throw new Exception("Невозможно вызвать компилятор, так как ни одно окно не активно");

}

if (activeChild.IsChanged) {

if (MessageBox.Show("Исходный текст программы " + activeChild.ProgramName + " был изменен. Будет выполенено сохранение текста программы. Продолжить?\nВыберите \"Нет\", если хотите вернуться и сохранить программу под другим именем", "Требуется сохранение", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation)

== System.Windows.Forms.DialogResult.No) return 1;

}

this.saveToolStripMenuItem_Click(this, new EventArgs());

if (activeChild.AssociatedFileName == null) return 1; // пользователь нажал "Отмена" в диалоге сохранения нового файла

this.c_txtOutput.Text = "*** Компиляция ***\r\n"; // было: this.extAppsStdOutput.Enqueue("*** Компиляция ***"); - но надо не в очередь, а напрямую, т.к. при новой компиляции окно вывода следует очистить. Ну и сразу записали, что начали компиляцию.

this.errorsDataGridView.Rows.Clear();

// приступаем к компиляции

string compilerKey = Enum.GetName(typeof(ExternalApplications), ExternalApplications.Compiler);

int exitCode = this.RunExternalApplication(ExternalApplications.Compiler, CLArgsMaskParser.Parse(this.externalApplicationInfoCollection[compilerKey].ArgumentsMask, activeChild.AssociatedFileName), true);

if (exitCode != 0) {

MessageBox.Show(string.Format("Не удалость скомпилировать {0}\nПодробности см. в окне \"Вывод\"", activeChild.ProgramName), "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

return exitCode;

}

private void startCompilationToolStripMenuItem_Click(object sender, EventArgs e) {

this.StartCompilation();

}

private void debugToolStripMenuItem_Click(object sender, EventArgs e) {

//MessageBox.Show("Заглушка запуска отладчика");

this.RunProgram(true);

}

private void compileAndRunToolStripMenuItem_Click(object sender, EventArgs e) {

this.RunProgram();

}

/// <summary>Запускает программу на выполнение заданном режиме</summary>

/// <param name="debug">Параметр, определяющий, следует ли запускать программу в режиме отладки</param>

private void RunProgram(bool debug = false) {

MDIForm activeChild = (MDIForm)this.ActiveMdiChild;

if (activeChild == null) {

return;

}

int exitCode = this.StartCompilation();

if (exitCode == 0) {

string linkerKey = Enum.GetName(typeof(ExternalApplications), ExternalApplications.Linker);

//exitCode = this.StartProcess(this.externalApplicationInfoCollection[linkerKey].ExeFileName, CLArgsMaskParser.Parse(this.externalApplicationInfoCollection[linkerKey].ArgumentsMask, activeChild.AssociatedFileName));

//this.c_txtOutput.Text += "*** Компоновка ***\r\n";

this.extAppsStdOutput.Enqueue("*** Компоновка ***");

exitCode = this.RunExternalApplication(ExternalApplications.Linker, CLArgsMaskParser.Parse(this.externalApplicationInfoCollection[linkerKey].ArgumentsMask, activeChild.AssociatedFileName), true);

if (exitCode == 0) {

ExternalApplications extApp = (debug)? ExternalApplications.Debugger : ExternalApplications.UUM32;

string key = Enum.GetName(typeof(ExternalApplications), extApp);

//this.StartProcess(this.externalApplicationInfoCollection[uumKey].ExeFileName, CLArgsMaskParser.Parse(this.externalApplicationInfoCollection[uumKey].ArgumentsMask, activeChild.AssociatedFileName));

//this.c_txtOutput.Text += "*** Запуск ***\r\n";

this.extAppsStdOutput.Enqueue("*** Запуск ***");

exitCode = this.RunExternalApplication(extApp, CLArgsMaskParser.Parse(this.externalApplicationInfoCollection[key].ArgumentsMask, activeChild.AssociatedFileName));

if (exitCode == 0) {

this.extAppsStdOutput.Enqueue("Программа успешно отработала.");//this.c_txtOutput.Text += "Программа успешно отработала.";

}

else {

this.extAppsStdOutput.Enqueue("Программа завершила работу некорректно. Код возврата: " + exitCode);//this.c_txtOutput.Text += "Программа завершила работу некорректно.";

}

}

else {

MessageBox.Show(string.Format("Не удалость скомпоновать {0}\nПодробности см. в окне \"Вывод\"", activeChild.ProgramName), "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

}

//-------------------------------------------------------------------------------------------

private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {

AboutBox about = new AboutBox();

about.ShowDialog();

about.Dispose();

}

private void MainForm_DragEnter(object sender, DragEventArgs e) {

if (!e.Data.GetDataPresent(DataFormats.FileDrop)) {

e.Effect = DragDropEffects.None;

}

else {

e.Effect = DragDropEffects.Copy;

}

}

// данный обработчик обслуживает и главную форму, и дочерние

private void MainForm_DragDrop(object sender, DragEventArgs e) {

if (e.Data.GetDataPresent(DataFormats.FileDrop)) {

foreach (string fName in (string[])e.Data.GetData(DataFormats.FileDrop)) {

if (Path.HasExtension(fName)) { // чтобы не давать открыть папку // TODO: возможно, было бы неплохо проверять и тип файла

this.OpenFile(fName);

}

}

}

}

private void highlightToolStripMenuItem_Click(object sender, EventArgs e) {

FontStyleSettingsForm fontStyler = new FontStyleSettingsForm();

fontStyler.BaseFont = (Font)this.childStyleSettings.BaseFont.Clone();

fontStyler.StylesEnabled = this.childStyleSettings.FontStylesEnabled;

fontStyler.StandartElementsFontStyles =

Misc.TemplateMethods<FontStyleSettingsForm.TextElementStyle>.GetCloneableListCopy(

this.childStyleSettings.StandartElementsFontStyles

);

fontStyler.KeywordsFontStyles =

Misc.TemplateMethods<FontStyleSettingsForm.TextElementStyle>.GetCloneableListCopy(

this.childStyleSettings.KeywordsFontStyles

);

fontStyler.BackgroundColor = this.childStyleSettings.BackgroundColor;

fontStyler.RunAsmBeforeShellStart = this.childStyleSettings.RunAsmBeforeShellStart;

fontStyler.AsmCommandLineArgument = this.childStyleSettings.AsmCommandlineArgument;

fontStyler.IsRelativePaths = this.allPathsAreRelative;

fontStyler.KeywordsFileName = GetAbsolutePathFromCurrent(this.childStyleSettings.KeywordsFileName);

if (fontStyler.ShowDialog() == System.Windows.Forms.DialogResult.OK) {

this.childStyleSettings.BaseFont = fontStyler.BaseFont;

this.childStyleSettings.FontStylesEnabled = fontStyler.StylesEnabled;

this.childStyleSettings.StandartElementsFontStyles = fontStyler.StandartElementsFontStyles;

this.childStyleSettings.KeywordsFontStyles = fontStyler.KeywordsFontStyles;

this.childStyleSettings.BackgroundColor = fontStyler.BackgroundColor;

this.childStyleSettings.RunAsmBeforeShellStart = fontStyler.RunAsmBeforeShellStart;

this.childStyleSettings.AsmCommandlineArgument = fontStyler.AsmCommandLineArgument;

this.childStyleSettings.KeywordsFileName = GetCurrentPathFromAbsolute(fontStyler.KeywordsFileName);

this.applyChildrenSettings();

}

fontStyler.Dispose();

}

private void externalAppsSettingsToolStripMenuItem_Click(object sender, EventArgs e) {

ExternalAppsSettingsForm extAppsConfigurator = new ExternalAppsSettingsForm(this.allPathsAreRelative);

ExternalApplications[] externalApplications = (ExternalApplications[])Enum.GetValues(typeof(ExternalApplications));

foreach (ExternalApplications extApp in externalApplications) {

string key = Enum.GetName(typeof(ExternalApplications), extApp);

string exe = this.GetAbsolutePathFromCurrent(this.externalApplicationInfoCollection[key].ExeFileName);

extAppsConfigurator.SetApplicationName(extApp, exe);

extAppsConfigurator.SetArgumentsMask(extApp, this.externalApplicationInfoCollection[key].ArgumentsMask);

}

if (extAppsConfigurator.ShowDialog() == System.Windows.Forms.DialogResult.OK) {

this.allPathsAreRelative = extAppsConfigurator.UseRelativePaths;

foreach (ExternalApplications extApp in externalApplications) {

string key = Enum.GetName(typeof(ExternalApplications), extApp);

string exe = GetCurrentPathFromAbsolute(extAppsConfigurator.GetApplicationName(extApp));

this.externalApplicationInfoCollection[key] = new ExternalApplicationInfo(exe, extAppsConfigurator.GetArgumentsMask(extApp));

}

this.SaveSettingsToXML();

}

extAppsConfigurator.Dispose();

}

private void linesNumerationToolStripMenuItem_Click(object sender, EventArgs e) {

LineNumerationSettingsForm numerationEditor = new LineNumerationSettingsForm(this.ChildNumerationSettings);

if (numerationEditor.ShowDialog() == System.Windows.Forms.DialogResult.OK) {

this.ChildNumerationSettings = new MDIForm.NumerationSetting(numerationEditor.NumerationNeed, numerationEditor.NumeratorForeColor, numerationEditor.NumeratorBackColor);

}

numerationEditor.Dispose();

}

private void c_txtOutput_TextChanged(object sender, EventArgs e) {

c_lblFocusCatcher.Focus();

c_txtOutput.SelectionStart = c_txtOutput.TextLength;

c_txtOutput.ScrollToCaret();

c_txtOutput.Refresh();

}

private void c_txtOutput_DoubleClick(object sender, EventArgs e) {

int curLine = c_txtOutput.GetLineFromCharIndex(c_txtOutput.GetFirstCharIndexOfCurrentLine());

string line = c_txtOutput.Lines[curLine].Trim().ToLower();

if (line.StartsWith("строка")) { // TODO: убрать константу, синхронизовать с ассемблером, т.к. сообщения формирует он

line = line.Replace("строка", "").Trim();

int ddot = line.IndexOf(':');

int lineNum = int.Parse(line.Substring(0, ddot)) - 1;

((MDIForm)this.ActiveMdiChild).JumpToLine(lineNum);

}

}

private void clearTxtOutToolStripMenuItem_Click(object sender, EventArgs e) {

this.c_txtOutput.Clear();

}

private void c_tmrExtAppsStdOutputDequeuer_Tick(object sender, EventArgs e) {

while (this.extAppsStdOutput.Count != 0) {

this.c_txtOutput.Text += this.extAppsStdOutput.Dequeue() + Environment.NewLine;

}

XmlDocument doc = new XmlDocument();

while (this.extAppsStdError.Count != 0) {

string text = this.extAppsStdError.Dequeue();

if (text != null) {

try {

doc.LoadXml(text);

XmlElement el = doc.DocumentElement;

this.errorsDataGridView.Rows.Add();

DataGridViewRow row = this.errorsDataGridView.Rows[this.errorsDataGridView.Rows.Count - 1];

row.Cells["ColumnFileName"].Value = el.Attributes["file"].Value;

row.Cells["ColumnLineNumber"].Value = el.Attributes["line"].Value;

row.Cells["ColumnErrorDescription"].Value = el.Attributes["description"].Value;

}

catch { }

}

}

}

private void errorsDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {

try {

DataGridViewRow row = this.errorsDataGridView.Rows[e.RowIndex];

string fileName = (string)row.Cells["ColumnFileName"].Value;

if (!string.IsNullOrEmpty(fileName)) {

MDIForm mdi = this.OpenFile(fileName);

string line = (string)row.Cells["ColumnLineNumber"].Value;

if (!string.IsNullOrEmpty(line)) {

int l = int.Parse(line) - 1;

mdi.JumpToLine(l);

}

}

}

catch { }

}

}

}

Приложение 9. Фрагмент исходного кода приложения «Макроассемблер для УУМ-32». Код класса, представляющего контрольную секцию программы

Файл "Sect\ControlSection.cs"

using System;

using System.Collections.Generic;

using UUM32Asm.Asm;

using UUM32Asm.Cmd;

using UUM32Asm.FileWriters;

using UUM32Asm.MachineCommands;

using UUM32Asm.Operands;

using UUM32Asm.PassLines;

using UUM32Asm.Tables;

namespace UUM32Asm.Section

{

/// <summary>Представляет управляющую секцию.</summary>

class ControlSection

{

/// <summary>Возвращает имя данной управляющей секции.</summary>

public string Name { get; private set; }

/// <summary>Возвращает список программных блоков данной управляющей секции.</summary>

public List<ProgramBlock> Blocks { get; private set; }

/// <summary>Возвращает имя файла, в котором объявлена данная секция.</summary>

public string FileName { get; private set; }

/// <summary>Таблица операций ассемблера.</summary>

OpTab opTab;

/// <summary>Таблица имен данной управляющей секции.</summary>

SymTab symTab;

/// <summary>Таблица изначальных и переопределенных в данной управляющей секции имен регистров.</summary>

SymTab regTab;

/// <summary>Очередь, содержащая экземпляры класса SecondPassLine с расширенной информацией о каждой строке программы. Требуется для второго просмотра.</summary>

Queue<SecondPassLine> firstPassOutQueue;

/// <summary>Список, содержащий элементы, необходимые для промежуточного просмотра</summary>

List<IntermediatePassLine> imPassList;

/// <summary>Список, содержащий строки, необходимые для рассчета неопределенных во время первого прохода констант</summary>

List<SecondPassLine> linesWithConstantsList;

/// <summary>Длина данной управляющей секции.</summary>

uint sectionLength; //TODO: потом все uint'ы сменить на int

/// <summary>Список внешних имен, которые следует импортировать в данную секцию</summary>

List<SymTabEl> importedNames;

/// <summary>Инициализирует новый экземпляр класса ControlSection с заданным именем.</summary>

/// <param name="name">Строка, задающая имя управляющей секции.</param>

public ControlSection(string name, string fileName)

{

this.Name = name;

this.FileName = fileName;

this.Blocks = new List<ProgramBlock>();

this.importedNames = new List<SymTabEl>();

}

/// <summary>Добавляет строку в определенный программный блок данной секции.</summary>

/// <param name="pl">Структура, содержащая информацию о строке программы.</param>

/// <param name="blockName">Имя блока, в который будет добавляться строка. Если не задано, строка добавляется в блок по умолчанию (есть в любой секции). Если блока с заданным именем не существует, он будет создан.</param>

public void AddCodeLine(PassLine pl, string blockName = "")

{

ProgramBlock currentBlock = null;

foreach (ProgramBlock blk in Blocks) // проверяем, существует ли блок с таким именем

{

if (blk.Name == blockName)

{

currentBlock = blk;

break;

}

}

if (currentBlock == null)

{

currentBlock = new ProgramBlock(blockName);

Blocks.Add(currentBlock);

}

currentBlock.AddCodeLine(pl);

}

/// <summary>Добавляет строку с директивой END в последний блок данной секции.</summary>

/// <param name="pl">Структура, содержащая информацию о строке программы.</param>

public void AddEndLine(PassLine pl)

{

Blocks[Blocks.Count - 1].AddCodeLine(pl);

}

/// <summary>Транслирует данную управляющую секцию в объектный код и выдает листинг.</summary>

/// <param name="optab">Таблица операций ассемблера.</param>

/// <param name="initRegTab">Исходная таблица регистров ассемблера.</param>

/// <param name="errorList">Список, содержащий сообщения об ошибках, возникших в ходе работы ассемблера.</param> // <param name="errorLog">Очередь, содержащая сообщения об ошибках, возникших в ходе работы ассемблера.</param>

/// <param name="lstFile">Экземпляр класса LstFileWriter для записи листинга.</param>

/// <param name="objFile">Экземпляр класса ObjFileWriter для записи объектного кода программы.</param>

public void Translate(OpTab optab, SymTab initRegTab, /*Queue<string> errorLog*/List<CompileError> errorList, LstFileWriter lstFile, ObjFileWriter objFile) {

opTab = optab;

regTab = new SymTab(initRegTab);

symTab = new SymTab();

int errorCount = /*errorLog*/errorList.Count; // т.к. лог ошибок общий, запомним, сколько ошибок было до нашей секции, и если после первого прохода это число не изменится, пойдем на следующие проходы

FirstPass(/*errorLog*/errorList);

if (/*errorLog*/errorList.Count != errorCount) {

}

else {

IntermediatePass(/*errorLog*/errorList);

if (/*errorLog*/errorList.Count != errorCount) {

}

else {

CalculateConstants(/*errorLog*/errorList);

if (/*errorLog*/errorList.Count != errorCount) {

}

else {

SecondPass(lstFile, objFile, /*errorLog*/errorList);

}

}

}

}

/// <summary>Возвращает список всех команд секции, упорядоченный по блокам (сначала инструкции 1го блока, затем 2го и т.д.).</summary>

/// <returns>Результат - список экземпляров класса PassLine.</returns>

private List<PassLine> GetCode()

{

int n = 0;

foreach (ProgramBlock block in Blocks)

n += block.Code.Count;

List<PassLine> res = new List<PassLine>(n);

foreach (ProgramBlock block in Blocks)

res.AddRange(block.Code);

return res;

}

/// <summary>Первый проход трансляции.</summary>

/// <param name="errorList">Список, содержащий информацию об ошибках, возникших в ходе работы ассемблера</param> // /// <param name="errorLog">Очередь, содержащая сообщения об ошибках, возникших в ходе работы ассемблера.</param>

void FirstPass(/*Queue<string> errorLog*/List<CompileError> errorList)

{

/// <summary>Счетчик размещений данной управляющей секции.</summary>

uint locCtr;

/// <summary>Начальный адрес данной управляющей секции.</summary>

uint startAddr;

firstPassOutQueue = new Queue<SecondPassLine>();

imPassList = new List<IntermediatePassLine>();

linesWithConstantsList = new List<SecondPassLine>();

List<PassLine> code = this.GetCode();

PassLine line = code[0];

try {

NumberOperand numOp = new NumberOperand(line.Operands);

locCtr = startAddr = numOp.Value;

}

catch (OperandException e) {

errorList.Add(/*new CompileError(line.LineNumber, e.Message)*/this.GetCompilerErrorUseMetadata(line, e.Message));

locCtr = startAddr = 0;

}

for (int i = 0; i < code.Count; i++) {

line = code[i];

SecondPassLine spLine = new SecondPassLine(line, locCtr);

if (line.Label != String.Empty && line.OpCode != AsmDirectives.Alias) {

if (symTab.Contains(line.Label)) {

errorList.Add(/*new CompileError(line.LineNumber, string.Format("Повторное опеределение метки \"{0}\".", line.Label))*/this.GetCompilerErrorUseMetadata(line, string.Format("Повторное опеределение метки \"{0}\".", line.Label)));

}

else if (regTab.Contains(line.Label)) {

errorList.Add(/*new CompileError(line.LineNumber, string.Format("Недопустимое имя метки \"{0}\" - это имя зарезервировано для регистра.", line.Label))*/this.GetCompilerErrorUseMetadata(line, string.Format("Недопустимое имя метки \"{0}\" - это имя зарезервировано для регистра.", line.Label)));

}

else {

try {

symTab.Add(new SymTabEl(line.Label, locCtr));

}

catch (SymTabException e) {

errorList.Add(/*new CompileError(line.LineNumber, e.Message)*/this.GetCompilerErrorUseMetadata(line, e.Message));

}

}

}

if (line.OpCode != String.Empty) {

switch (line.OpCode) {

case AsmDirectives.Start: case AsmDirectives.End: case AsmDirectives.CSect: case AsmDirectives.Export: {

// все эти директивы обрабатываются не в этом проходе

break;

}

case AsmDirectives.Import: {

// импортируемые имена добавляем в первом проходе, т.к. они могут потребоваться уже в промежуточном проходе

try {

NameListOperand nlstOp = new NameListOperand(line.Operands);

foreach (string name in nlstOp.NameList) {

SymTabEl ste = symTab.Find(name);

if (ste != null) {

//errorLog.Enqueue(string.Format("Строка {0}: Невозможно импортировать имя \"{1}\" в секцию {2}. Метка с таким именем уже объявлена в данной секции.", line.LineNumber, name, this.Name)); //TODO: эта ошибка накладывается на исключение ArgumentException класса ImportNamesRec, выбрасываемое при добавлении одинаковых имен

errorList.Add(this.GetCompilerErrorUseMetadata(line, string.Format("Невозможно импортировать имя \"{0}\" в секцию \"{1}\". Метка с таким именем уже объявлена в данной секции.", name, this.Name))/*new CompileError(line.LineNumber, string.Format("Невозможно импортировать имя \"{0}\" в секцию \"{1}\". Метка с таким именем уже объявлена в данной секции.", name, this.Name))*/); //TODO: эта ошибка накладывается на исключение ArgumentException класса ImportNamesRec, выбрасываемое при добавлении одинаковых имен

}

else if (regTab.Contains(name)) {

//errorLog.Enqueue(string.Format("Строка {0}: Невозможно импортировать имя \"{1}\" в секцию {2}. Имя совпадает с одним из регистров.", line.LineNumber, name, this.Name));

errorList.Add(this.GetCompilerErrorUseMetadata(line, string.Format("Невозможно импортировать имя \"{0}\" в секцию \"{1}\". Имя зарезервировано для одного из регистров.", name, this.Name))/*new CompileError(line.LineNumber, string.Format("Невозможно импортировать имя \"{0}\" в секцию \"{1}\". Имя зарезервировано для одного из регистров.", name, this.Name))*/);

}

else {

SymTabEl imported = new SymTabEl(name, 0);

imported.Imported = true;

symTab.Add(imported);

importedNames.Add(imported); // во втором проходе содержимое этого списка запишется в объектный файл

}

}

break;

}

catch (ArgumentException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

catch /*(Exception e)*/ {

throw;

}

break;

}

case AsmDirectives.ResB: case AsmDirectives.ResH: case AsmDirectives.ResW: {

try {

NumberOperand nOp = new NumberOperand(line.Operands);

spLine.Op = nOp;

byte k = AsmDirectives.SizeOfType(line.OpCode);

locCtr += nOp.Value * k;

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

break;

}

case AsmDirectives.Byte: case AsmDirectives.Half: case AsmDirectives.Word: {

linesWithConstantsList.Add(spLine);

try { // исключение возникнет, если строка-инициализатор массива содержала пустые элементы (например: 1, 2, , 4, 5)

locCtr += (uint)ConstantOperand.CalculateArraySize(spLine.FirstPassLine.Operands, (ConstantType)AsmDirectives.SizeOfType(spLine.FirstPassLine.OpCode));

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

break;

}

case AsmDirectives.Equate: {

if (!string.IsNullOrEmpty(line.Label)/*line.Label != String.Empty*/) { // если при директиве Equate есть метка, то все в порядке - она ранее была добавлена в таблицу имен

SymTabEl el = symTab.Find(line.Label); // TODO: на всякий отследить отсутствие элемента в SymTab

el.Undefined = true; // отметили, что данная запись таблицы имен является неопределенной

imPassList.Add(new IntermediatePassLine(spLine, el)); // запомнили строку с директивой Equate для промежуточного просмотра

}

else {

errorList.Add(this.GetCompilerErrorUseMetadata(line, string.Format("Директива {0} без метки.", AsmDirectives.Equate))/*new CompileError(line.LineNumber, string.Format("Директива {0} без метки.", AsmDirectives.Equate))*/);

}

// locCtr увеличивать не требуется

break;

}

case AsmDirectives.Alias: {

try {

if (string.IsNullOrEmpty(line.Label)) {

throw new UUM32AsmException(string.Format("Директива {0} без метки", AsmDirectives.Alias));

}

else if (regTab.Contains(line.Label)) {

throw new UUM32AsmException(string.Format("Имя \"{0}\" совпадает со стандартным именем одного из регистров либо было объявлено ранее", line.Label));

}

NameOperand nop = new NameOperand(spLine.FirstPassLine.Operands);

SymTabEl reg = regTab.Find(nop.Name);

if (reg != null) {

regTab.Add(new SymTabEl(line.Label, reg.Address));

}

else {

throw new UUM32AsmException(string.Format("Регистра с именем \"{0}\" не существует", nop.Name));

}

}

catch (UUM32AsmException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

catch (ArgumentException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

break;

}

case MacroAsm.MacroAssembler.Directives.Include:

case MacroAsm.MacroAssembler.Directives.MacroStart:

case MacroAsm.MacroAssembler.Directives.MacroEnd: {

errorList.Add(this.GetCompilerErrorUseMetadata(line, string.Format("Директиву \"{0}\" можно использовать только в макрокоде. Смените расширение файла на \"{1}\"", line.OpCode, FileExtensions.MacroassemblerSourceFileExtension))/*new CompileError(line.LineNumber, string.Format("Директиву \"{0}\" можно использовать только в макрокоде. Смените расширение файла на \"{1}\"", line.OpCode, FileExtensions.MacroassemblerSourceFileExtension))*/);

break;

}

default: {

try {

Command cmd = new Command(line.OpCode, opTab);

locCtr += cmd.Size;

}

catch (CommandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(line, e.Message)/*new CompileError(line.LineNumber, e.Message)*/);

}

break;

}

}

}

firstPassOutQueue.Enqueue(spLine);

}

sectionLength = locCtr - startAddr;

}

/// <summary>Выполняет промежуточный проход трансляции.</summary>

/// <param name="errorList">Список, содержащий информацию об ошибках, возникших в ходе работы ассемблера</param> // /// <param name="errorLog">Очередь, содержащая сообщения об ошибках, возникших в ходе работы ассемблера.</param>

void IntermediatePass(/*Queue<string> errorLog*/List<CompileError> errorList) {

foreach (IntermediatePassLine imLine in imPassList) {

try {

imLine.Recalculate(imPassList, symTab);

if (imLine.ContainsImportedNames) {

throw new OperandException(string.Format("Директива {0} не может оперировать с импортированными именами, так как на этапе компиляции значения этих имен неопределены.", AsmDirectives.Equate));

}

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(imLine.SecPassLine.FirstPassLine, e.Message)/*new CompileError(imLine.SecPassLine.FirstPassLine.LineNumber, e.Message)*/);

}

catch (Exception e) { // TODO: разобраться с типом исключения

errorList.Add(this.GetCompilerErrorUseMetadata(imLine.SecPassLine.FirstPassLine, string.Format("Неизвестная ошибка: {0}", e.Message))/*new CompileError(imLine.SecPassLine.FirstPassLine.LineNumber, string.Format("Неизвестная ошибка: {0}", e.Message))*/); //TODO: отредактировать строку сообщения и сменить его тип после отладки

}

}

foreach (IntermediatePassLine imLine in imPassList) { // теперь проверим, все ли записи определены

if (imLine.UndefinedElementsCount > 0) {

errorList.Add(this.GetCompilerErrorUseMetadata(imLine.SecPassLine.FirstPassLine, string.Format("Невозможно связать имя \"{1}\" со значением выражения \"{0}\". Проверьте выражения на рекурсию.", imLine.SecPassLine.FirstPassLine.Operands, imLine.SecPassLine.FirstPassLine.Label))/*new CompileError(imLine.SecPassLine.FirstPassLine.LineNumber, string.Format("Невозможно связать имя \"{1}\" со значением выражения \"{0}\". Проверьте выражения на рекурсию.", imLine.SecPassLine.FirstPassLine.Operands, imLine.SecPassLine.FirstPassLine.Label))*/);

}

}

}

/// <summary>Выполняет вычисление числовых значений констант, неопределенных во время первого прохода по причине участия в формировании константы неопределенного имени (метки директивы Equate)</summary>

/// <param name="errorList">Список, содержащий информацию об ошибках, возникших в ходе работы ассемблера</param> // /// <param name="errorLog">Очередь, содержащая сообщения об ошибках, возникших в ходе работы ассемблера.</param>

void CalculateConstants(/*Queue<string> errorLog*/List<CompileError> errorList) {

foreach (SecondPassLine spLine in this.linesWithConstantsList) {

try {

ConstantType ct = (ConstantType)AsmDirectives.SizeOfType(spLine.FirstPassLine.OpCode);

ConstantOperand cOp = new ConstantOperand(spLine.FirstPassLine.Operands, ct, symTab, spLine.Addr);

if (cOp.Undefined) {

throw new OperandException("Невозможно вычислить значение, задающее константу");

}

spLine.Op = cOp;

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(spLine.FirstPassLine, e.Message)/*new CompileError(spLine.FirstPassLine.LineNumber, e.Message)*/);

}

}

}

/// <summary>Выполняет второй проход трансляции.</summary>

/// <param name="lstFile">Ссылка на экземпляр класса LstFileWriter для записи листинга.</param>

/// <param name="objFile">Ссылка на экземпляр класса ObjFileWriter для записи объектного кода программы.</param>

/// <param name="errorList">Список, содержащий информацию об ошибках, возникших в ходе работы ассемблера</param> // /// <param name="errorLog">Ссылка на очередь, содержащую сообщения об ошибках, возникших в ходе работы ассемблера.</param>

void SecondPass(LstFileWriter lstFile, ObjFileWriter objFile, /*Queue<string> errorLog*/List<CompileError> errorList) {

List<byte> objCode = null;

SecondPassLine spLine = firstPassOutQueue.Dequeue();

lstFile.WriteLine(spLine, null);

objFile.AddHeaderRec(spLine.FirstPassLine.Label, sectionLength);

while (firstPassOutQueue.Count > 0/*spLine.FirstPassLine.OpCode != AsmDirectives.End*/) {

spLine = firstPassOutQueue.Dequeue();

PassLine fpLine = spLine.FirstPassLine;

MachineCommand machineCommand = null;

ObjFileWriter.BodyRecTypes bodyRecType = ObjFileWriter.BodyRecTypes.Code; // нужна для разбиения obj-файла на строки код/данные

objCode = null;

if (AsmDirectives.IsAsmDirective(fpLine.OpCode)) {

if (AsmDirectives.IsConstantDirective(fpLine.OpCode)) { //(fpLine.OpCode == AsmDirectives.Byte || fpLine.OpCode == AsmDirectives.Half || fpLine.OpCode == AsmDirectives.Word)

objCode = ((ConstantOperand)spLine.Op/*Constant*/).ByteList;

bodyRecType = ObjFileWriter.BodyRecTypes.Data;

objFile.AddToBodyRec(objCode, bodyRecType); // TODO: если захочешь вернуться к старому варианту, когда объ код добавлялся после блока else этого if'а, закомменть эту строку, строку добавления объ кода ветви else и раскомменть строку добавления объ кода после блока else

}

else if (AsmDirectives.IsResDirective(fpLine.OpCode)) {

objFile.StartNewBodyRec(((NumberOperand)spLine.Op).Value * AsmDirectives.SizeOfType(fpLine.OpCode));

}

else if (fpLine.OpCode == AsmDirectives.Export) {

try {

NameListOperand nlstOp = new NameListOperand(fpLine.Operands);

foreach (string name in nlstOp.NameList) {

SymTabEl ste = symTab.Find(name);

if (ste != null) {

// TODO: оказывается, имя секции не экспортируется автоматически

objFile.AddToCurrentExpNamesRec(ste);

}

else {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, string.Format("Невозможно экспортировать имя \"{0}\" из секции {1}. Не найдено объявление данного имени.", name, this.Name))/*new CompileError(fpLine.LineNumber, string.Format("Невозможно экспортировать имя \"{0}\" из секции {1}. Не найдено объявление данного имени.", name, this.Name))*/);

}

}

}

catch (ArgumentException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, e.Message)/*new CompileError(fpLine.LineNumber, e.Message)*/);

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, e.Message)/*new CompileError(fpLine.LineNumber, e.Message)*/);

}

catch (Exception e) {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, string.Format("Неизвестная ошибка: {0}.", e.Message))/*new CompileError(fpLine.LineNumber, string.Format("Неизвестная ошибка: {0}.", e.Message))*/);

}

}

else if (fpLine.OpCode == AsmDirectives.Import) {

foreach (SymTabEl stel in importedNames) {

objFile.AddToCurrentImpNamesRec(stel.Label);

}

}

}

else if (!fpLine.OpCode.Equals(string.Empty)) { // если строка содержит операцию //if (opTab.Contains(fpLine.OpCode))

Command cmd;

try {

cmd = new Command(fpLine.OpCode, opTab);

}

catch { //TODO: разобраться здесь

throw new UUM32AsmException("Второй проход: нет комнды в OpTab!");

}

// анализ числа операндов

string[] ops = { String.Empty, String.Empty };

switch (cmd.OperandCount) {

case 0:

if (fpLine.Operands != String.Empty) {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, string.Format("У команды \"{0}\" не должно быть операндов.", fpLine.OpCode))/*new CompileError(fpLine.LineNumber, string.Format("У команды \"{0}\" не должно быть операндов.", fpLine.OpCode))*/);

}

break;

case 1:

ops[0] = fpLine.Operands;

break;

case 2:

int i = fpLine.Operands.IndexOf(',');

if (i <= 0 || i == (fpLine.Operands.Length - 1)) {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, string.Format("У команды \"{0}\" должно быть два операнда.", fpLine.OpCode))/*new CompileError(fpLine.LineNumber, string.Format("У команды \"{0}\" должно быть два операнда.", fpLine.OpCode))*/);

break;

}

ops[0] = fpLine.Operands.Substring(0, i).Trim();

ops[1] = fpLine.Operands.Remove(0, i + 1).Trim();

break;

}

Operand[] Operands = { null, null };

for (int i = 0; i < cmd.OperandCount; i++) {

try {

switch (cmd.Operands[i]) {

case OperandTypes.Number:

try {

Operands[i] = new NumberOperand(ops[i]);

}

catch {

Operands[i] = new NumberOperand();

throw;

}

break;

case OperandTypes.Register:

try {

Operands[i] = new RegisterOperand(ops[i], regTab);

}

catch {

Operands[i] = new RegisterOperand();

throw;

}

break;

case OperandTypes.Memory:

try {

Operands[i] = new AddressOperand(ops[i], symTab, spLine.Addr);

}

catch {

//Operands[i] = new AddressOperand();

Operands[i] = AddressOperand.CreateDummyAddressOperand();

throw;

}

break;

}

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(fpLine, e.Message)/*new CompileError(fpLine.LineNumber, e.Message)*/);

}

}

switch (cmd.Format) {

case 1:

machineCommand = new FirstTypeCommand(cmd.Code, cmd.Eop);

break;

case 2:

if (cmd.Operands[0] == OperandTypes.Register) {

machineCommand = new SecondTypeCommand(cmd.Code, cmd.Eop, (RegisterOperand)Operands[0], (RegisterOperand)Operands[1]);

}

else if (cmd.Operands[0] == OperandTypes.Number) {

machineCommand = new SecondTypeCommand(cmd.Code, cmd.Eop, (NumberOperand)Operands[0]);

}

break;

case 3:

if (cmd.Operands[0] == OperandTypes.Memory) {

machineCommand = new ThirdTypeCommand(cmd, (AddressOperand)Operands[0], spLine.Addr + cmd.Size);

}

else if (cmd.Operands[0] == OperandTypes.Register) {

machineCommand = new ThirdTypeCommand(cmd, (RegisterOperand)Operands[0], (AddressOperand)Operands[1], spLine.Addr + cmd.Size);

}

break;

case 4:

if (cmd.Operands[0] == OperandTypes.Memory) {

machineCommand = new FourthTypeCommand(cmd, (AddressOperand)Operands[0], spLine.Addr + cmd.Size);

}

else if (cmd.Operands[0] == OperandTypes.Register) {

machineCommand = new FourthTypeCommand(cmd, (RegisterOperand)Operands[0], (AddressOperand)Operands[1], spLine.Addr + cmd.Size);

}

break;

}

objCode = machineCommand.GetByteList();

bool bodyRecAdded = false;

if ((cmd.Format == 3 || cmd.Format == 4)) { // для команд 3 и 4 формата при необходимости надо добавить модификаторы

AddressCommand addressMachineCommand = (AddressCommand)machineCommand;

if (addressMachineCommand.NeedsModification) {

objFile.AddToNewBodyRec(objCode); // выносим модифицируюмую запись в отдельную строку, чтобы было легче читать объ. код

bodyRecAdded = true;

foreach (ObjFileWriter.ModifierRec mRec in addressMachineCommand.ModifierRecords) {

objFile.AddModifierRec(mRec);

}

}

}

if (!bodyRecAdded) {

objFile.AddToBodyRec(objCode, bodyRecType);

}

}

else { // строка содержит только метку

;

}

lstFile.WriteLine(spLine, objCode);

}

// если послденяя директива была END, надо определить точку входа

if (spLine.FirstPassLine.OpCode == AsmDirectives.End && spLine.FirstPassLine.Operands != String.Empty) {

try {

AddressOperand op = new AddressOperand(spLine.FirstPassLine.Operands, symTab, spLine.Addr);

objFile.AddEndRec((uint)op.Value);

}

catch (OperandException e) {

errorList.Add(this.GetCompilerErrorUseMetadata(spLine.FirstPassLine, e.Message)/*new CompileError(spLine.FirstPassLine.LineNumber, e.Message)*/);

}

}

else {

objFile.AddEndRec();

}

}

/// <summary>

/// Возвращает ошибку компиляции, по возможности заполняя поля имени файла и номера строки из метаданных макроассемблера, лежащих в заданной строке PassLine.

/// Если метаданных нет, берется текущее имя файла для данной секции, номер строки берется из заданной строки PassLine.

/// </summary>

/// <param name="line"></param>

/// <param name="errorText"></param>

private CompileError GetCompilerErrorUseMetadata(PassLine line, string errorText) {

CompileError err = new CompileError();

err.Description = errorText;

if (!string.IsNullOrEmpty(line.MetaComment)) {

int sepIndex = line.MetaComment.LastIndexOf(PassLine.MetaDataSeparator);

err.FileName = line.MetaComment.Substring(0, sepIndex);

err.LineNumber = int.Parse(line.MetaComment.Substring(sepIndex + 1));

}

else {

err.FileName = this.FileName;

err.LineNumber = line.LineNumber;

}

return err;

}

}

}

Размещено на Allbest.ru

...

Подобные документы

  • Разработка программного обеспечения решения задач численного вычисления определенных интегралов. Анализ задачи, методы, инструменты: требования к аппаратным ресурсам и программным средствам. Руководство пользователя, тестирование приложения, применение.

    курсовая работа [1,6 M], добавлен 27.08.2012

  • Область применения и требования создаваемого Web-приложения. Требования к техническому и программному обеспечению. Разработка структуры Web-приложения и выбор средств программной реализации. Программная реализация Web-приложения. Структура базы данных.

    дипломная работа [1,4 M], добавлен 03.06.2014

  • Общие сведения о платформе Microsoft NET Framework. Разработка приложения "Поставка и реализация программного обеспечения", содержащего базу данных о каталогах адресов в Internet. Описание логической структуры. Требования к техническому обеспечению.

    курсовая работа [2,4 M], добавлен 28.06.2011

  • Возможности среды программирования delphi при разработке приложения с визуальным интерфейсом. Разработка спецификации программного обеспечения и на ее основе кода программного продукта. Отладка программы "трассировкой", ее тестирование и оптимизация.

    курсовая работа [501,4 K], добавлен 07.12.2016

  • Цели и задачи программной инженерии. Понятие программного обеспечения. Шесть принципов эффективного использования программного обеспечения. Виды программного обеспечения: общесистемное, сетевое и прикладное. Принципы построения программного обеспечения.

    курсовая работа [30,4 K], добавлен 29.06.2010

  • Общая характеристика и функциональное назначение проектируемого программного обеспечения, требования к нему. Разработка и описание интерфейса клиентской и серверной части. Описание алгоритма и программной реализации приложения. Схема базы данных.

    курсовая работа [35,4 K], добавлен 12.05.2013

  • Разбиение данных по таблицам и создание связей между таблицами. Нормализация и проектирование сценария работы базы данных. Выбор программного обеспечения. Требования к аппаратным и программным средствам для работы созданного программного продукта.

    курсовая работа [30,2 K], добавлен 23.01.2011

  • Возможности среды программирования delphi при разработке приложения с визуальным интерфейсом. Отладка программных модулей с использованием специализированных программных средств. Тестирование программного обеспечения. Оптимизация программного кода.

    курсовая работа [974,0 K], добавлен 21.12.2016

  • Требования к программному средству. Спецификация качества программного обеспечения. Требования к эргономике и технической эстетики. Стадии и этапы разработки, порядок контроля и приемки. Проектирование архитектуры приложения, руководство пользователя.

    курсовая работа [381,6 K], добавлен 20.06.2012

  • Разработка и реализация демонстрационного многопоточного приложения. Выбор основных средств реализации. Описание логики работы приложения и разработка программного обеспечения. Описание пользовательского интерфейса. Реализация потоков в Delphi.

    курсовая работа [462,5 K], добавлен 10.08.2014

  • Проектирование программного модуля: сбор исходных материалов; описание входных и выходных данных; выбор программного обеспечения. Описание типов данных и реализация интерфейса программы. Тестирование программного модуля и разработка справочной системы.

    курсовая работа [81,7 K], добавлен 18.08.2014

  • Описание истории развития информационных технологий. Исследование предпочтений по использованию программного обеспечения пользователя персонального компьютера начального уровня и разработка интерфейсного приложения в среде программирования Delphi.

    дипломная работа [2,0 M], добавлен 14.01.2012

  • Требования к аппаратным и операционным ресурсам. Логическая и физическая организация. Состав основных классов проекта. Технико-экономическое обоснование разработки программного средства. Задержки при обработке данных. Разработка интерфейса приложения.

    дипломная работа [4,4 M], добавлен 16.06.2017

  • Разработка базы данных и прикладного программного приложения с целью обеспечения хранения, накопления и предоставления информации об учащихся МБОУ "Средняя общеобразовательная школа №18" г. Грозный. Методы обеспечения информационной безопасности.

    дипломная работа [2,9 M], добавлен 25.06.2015

  • Разработка программного продукта учёта работы предприятия "Зеленстрой". Проектирование предметной области: концептуальное моделирование, интерфейс приложения. Реализация автоматизированной информационной системы, требования к аппаратным средствам.

    курсовая работа [679,8 K], добавлен 11.11.2010

  • Архитектура и история создания операционной системы Android. Язык программирования Java. Выбор средства для реализации Android приложения. Программная реализация Android приложения. Проведение тестирования разработанного программного обеспечения.

    курсовая работа [167,8 K], добавлен 18.01.2017

  • Практические аспекты использования прикладного программного обеспечения при разработке базы данных "Аудиторный фонд ГБОУ СПО "Старооскольский педагогический колледж". Системы управления базами данных. Описание и функциональные возможности приложения.

    курсовая работа [360,4 K], добавлен 07.10.2014

  • Этапы разработки программного приложения, выполняющего синтаксический анализ программы на языке С и форматирование текста программы на языке С. Требования к программному обеспечению и интерфейсу. Конфигурация технических средств и оценка надежности.

    курсовая работа [1,6 M], добавлен 22.06.2011

  • Понятие и ключевое отличие распределенной разработки программного обеспечения, его достоинства и недостатки. Концептуальное решение и выбор типа разработки. Особенности программного обеспечения с открытым исходным кодом. Идея и развитие Open Source.

    курсовая работа [97,7 K], добавлен 14.12.2012

  • Изучение стадий и этапов разработки программного обеспечения и эксплуатационных документов. Обзор создания архитектуры, распространения и поддержки системы приложения. Анализ проблем интерфейсов между программным обеспечением и операционной системой.

    курсовая работа [1,2 M], добавлен 30.04.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.