Разработка программы-отладчика

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    2,11 Мб
  • Опубликовано:
    2012-11-15
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Разработка программы-отладчика

Министерство Образования и Науки Украины

Севастопольский Национальный Технический Университет

Кафедра Кибернетики и вычислительной техники









Курсовой проект по дисциплине «Программирование»


Выполнил:

Юрков А.А

Приняла:

Смагина А.О.






Севастополь 2012

Содержание

Введение

.        Постановка задачи

.        Анализ набора команд

.        Анализ структуры микропроцессора и выбор моделирующих переменных

.        Описание входных и выходных данных

.        Разработка программы (алгоритм, логика программы)

.        Описание программы

.        Отладка и тестирование

Библиографический список

Приложения

Введение

Ассе́мблер (сборщик) - компьютерная программа, компилятор исходного текста программы, написанной на языке ассемблера, в программу на машинном языке.

Ассемблирование может быть не первым и не последним этапом на пути получения исполнимого модуля программы. Так, многие компиляторы с языков программирования высокого уровня выдают результат в виде программы на языке ассемблера, которую в дальнейшем обрабатывает ассемблер. Также результатом ассемблирования может быть не исполнимый, а объектный модуль, содержащий разрозненные блоки машинного кода и данных программы, из которого (или из нескольких объектных модулей) в дальнейшем с помощью программы-компоновщика может быть скомпонован исполнимый файл.

Процесс трансляции программы на языке ассемблера в объектный код принято называть ассемблированием. В отличие от компилирования, ассемблирование - более или менее однозначный и обратимый процесс. В языке ассемблера каждой мнемонике соответствует одна машинная инструкция, в то время как в языках программирования высокого уровня за каждым выражением может скрываться большое количество различных инструкций. В принципе, это деление достаточно условно, поэтому иногда трансляцию ассемблерных программ также называют компиляцией. После ассемблирования полученный объектный код понятен для процессора и успешно им выполняется.

Курсовой проект посвящён разработке программной модели процессора. Он делится на 3 части : разработка программы ассемблера, которая из текстового набора команд будет генерировать объектный код, понятный процессору; разработка программы отладчика, которая непосредственно выполняет команды, изложенные в объектном коде; разработка интерфейса для удобного взаимодействия и связи вышеупомянутых программ.

Данный вариант курсового проекта посвящён разработке программы-отладчика, использующую некоторую систему команд. Программа отладчик непосредственно выполняет команды, написанные на языке Ассемблер и транслированные в объектный код. Предполагается, что программа-ассемблер, генерирующая объектный файл, уже разработана и производит трансляцию корректно.

1. Постановка задачи

Разработать программную модель микропроцессора, разработать программу кросс отладки. Предусмотреть выполнение пошагового режима отладки. Отладчик должен имитировать рабочий цикл процессора для каждой команды. Регистры процессора однобайтные, объем оперативной памяти 256 байт.

Согласно варианту, была предложена следующая структура модели микропроцессора:


Набор команд:


2. Анализ набора команд

Согласно варианту, была предложена следующая система команд.


Команды ассемблера имеют длину один или два байта. Биты 0-3 первого байта определяют код в соответствии с таблицей команд (биты 0-3). Биты 4-7 первого байта задают регистры (если они есть).

Регистры A, B, C, D соответсвуют двоичным кодам 00, 01, 10, 11 соответственно.

Второй байт (если есть) задаёт адрес памяти или константу (в зависимости от команды).

Рассмотрим команды :

1)ADD регистр1, регистр2.

в регистр команд заносится значение 0000

в промежуточные регистры заносятся значения регистра1, регистра2

регистры передаются в АЛУ

производится сложение двух чисел

формируются флаги

результат сложения заносится в регистр1

команда однобайтная, следовательно СЧАК увеличиваем на 1

)ADD регистр1, память

в регистр команд заносится значение 0001

в промежуточные регистры заносятся значения регистра1, второй операнд берётся по указанному адресу памяти (подгружается второй байт)

операнды передаются в АЛУ

производится сложение двух чисел

формируются все флаги

результат сложения заносится в регистр1

команда двухбайтная, следовательно СЧАК увеличиваем на 2

)AND регистр1, регистр2

в регистр команд заносится значение 0010

в промежуточные регистры заносятся значения регистра1, регистра2

операнды передаются в АЛУ

производится поразрядное умножение двух чисел (логическое И)

формируются все флаги, кроме переполнения

результат сложения заносится в регистр1

команда однобайтная, следовательно СЧАК увеличиваем на 1

)OR регистр1, регистр2

в регистр команд заносится значение 0011

в промежуточные регистры заносятся значения регистра1, регистра2

операнды передаются в АЛУ

производится поразрядное сложение двух чисел (логическое ИЛИ)

формируются все флаги, кроме переполнения

результат сложения заносится в регистр1

команда однобайтная, следовательно СЧАК увеличиваем на 1

)NOT регистр

в регистр команд заносится значение 0100

в промежуточный регистр заносятся значения регистра

операнд передаётся в АЛУ

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

формируются все флаги, кроме переполнения

результат сложения заносится в регистр

команда однобайтная, следовательно СЧАК увеличиваем на 1

)MOV регистр, константа

в регистр команд заносится значение 0101

-в заданный регистр заносится константа (подгружается второй байт)

команда двухбайтная, следовательно СЧАК увеличиваем на 2

)LOAD регистр, память

в регистр команд заносится значение 0110

в заданный регистр заносится значение, взятое из памяти по указанному адресу (подгружается второй байт)

команда двухбайтная, следовательно СЧАК увеличиваем на 2

)STORE регистр, память

в регистр команд заносится значение 0111

в заданный адрес памяти загружается значение регистра (подгружается второй байт)

команда двухбайтная, следовательно СЧАК увеличиваем на 2

)JMP адрес

в регистр команд заносится значение 1000

производится безусловный переход программы по указанному адресу,

СЧАКу присваивается значение адреса

)JZ адрес

в регистр команд заносится значение 1001

проверяется значение флага нуля. Если true, то производится переход программы по указанному адресу, т.е СЧАКу присваивается значение адреса. Если false, продолжается выполнение программы, СЧАК увеличиваем на 2.

)JO адрес

в регистр команд заносится значение 1010

проверяется значение флага переполнения. Если true, то производится переход программы по указанному адресу, т.е СЧАКу присваивается значение адреса. Если false, продолжается выполнение программы, СЧАК увеличиваем на 2.

)JL адрес

в регистр команд заносится значение 1011

проверяется значение флага отрицательности числа. Если true, то производится переход программы по указанному адресу, т.е СЧАКу присваивается значение адреса. Если false, продолжается выполнение программы, СЧАК увеличиваем на 2.

)JNZC регистр, адрес

в регистр команд заносится значение 1100

проверяется значение флага нуля. Если true, то продолжается выполнение программы, СЧАК увеличиваем на 2. Если false, то выполняется переход по указанному адресу, т.е СЧАКу присваивается значение адреса, выполняется декремент регистра (вычитание единицы)

)CLF

в регистр команд заносится значение 1101

значение всех флагов устанавливается в false. СЧАК увеличиваем на 1 , т.к команда однобайтная.

)CALL адрес

в регистр команд заносится значение 1110

в регистр D заносится значение СЧАКа+2 (т.к при возврате выполнение программы будет начинаться уже со следующей команды)

выполняется переход в подпрограмму по указанному адресу, т.е СЧАКу присваивается значение адреса.

)RET

в регистр команд заносится значение 1111

производится возврат из подпрограммы, значению СЧАКа присваивается текущее значение регистра D. (туда был занесён предыдущий адрес командой CALL)

Команды можно разделить на:

арифметическо-логические (ADD, AND, OR, NOT)

команды для пересылки данныъ (MOV, LOAD, STORE)

команды перехода (JMP, JO, JZ, JL, JNZC)

команды подпрограмм(CALL, RET)

команда очистки флагов (CLF)

При вызове арифметическо-логической команды операнды(или операнд) передаются в АЛУ. Только эти команды формируют флаги.

При вызове команд для пересылки данных производится запись чисел в регистр или по адресу памяти из регистра, памяти, или входной константы.

При вызове команды перехода изменяется только СЧАК. В большинстве команд проверяется, установлены ли некоторые флаги.

Список команд, количество байтов, их структура и примеры приведены в таблице:


В объектном файле перед байтами команды должен присутствовать байт [01]. Он определяет, что следующий байт будет командой, а не адресом.

Однако, если присутствует команда ORG, которая задаёт адрес памяти, перед ней должен быть байт [00].

Если неважно, какое значение находится в части байта, то эти биты заполняются нулями. Однако отладчик не использует их в программе, поэтому теоретически там могут находиться любые значения.

. Анализ структуры микропроцессора и выбор моделирующих переменных

Согласно структуре, микропроцессор содержит:

4 регистра общего назначения (A. B. C. D)

Оперативную память 256 байт, у которой есть адрес и данные, которые хранятся по указанному адресу

СЧАК - счётчик адреса команд. С его помощью осуществляется перемещение по памяти, доступ и запись данных в память

Регистр команд - переменная, значение которой будет соответствовать определённой команде процессора.

АЛУ - Арифметическо-логическое устройство - осуществляет действия над числами, такие как : сложение, побитовое И, побитовое ИЛИ, инверсия.

Промежуточные регистры - при выполнении операций сложения, побитового И, побитового ИЛИ, инверсии два (или один) операнда заносятся в них для последующей передачи в АЛУ.

Результат - после выполнения операций над операндами(если они есть), результат передаётся в регистр или в память по адресу, в зависимости от команды.

Флаги - формируются, если выполнялась арифметическая или логическая операция. Флаг переполнения, флаг нуля, и флаг отрицательности числа. В данной структуре они не влияют на результат.

Для реализации регистров целесообразно применить объект - для более удобного доступа. Так же объект будет удобен для передачи в методы в качестве параметра. В объекте полями будет выступать массив из 4-х элементов - 4 регистра A, B, C, D. Тип - числовой.

Для реализации оперативной памяти так же целесообразно применить объект - причины рассмотрены в предыдущем пункте. В объекте полями будет выступать массив из 256 элементов - объём памяти. Тип - числовой.

АЛУ удобнее всего будет реализовать отдельным классом для упорядоченности кода программы. На основе класса создать экземпляр, через который и будет осуществляться доступ к методам - сложение, И, ИЛИ, НЕ. Эти методы должны возвращать некоторый результат. Так же АЛУ будет формировать флаги, которые удобно сделать статическими переменными этого класса. Тип - логический.

Переменную СЧАК необходимо сделать статической, т.к к ней будет постоянное обращение, возможно из разных классов. Тип - числовой.

Для реализации Регистра Команд необходимо использовать переменную. В неё будут заносится номера команд и, в зависимости от её значения, будут выполняться соответствующие операции. Тип - числовой.

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

. Описание входных и выходных данных

Входные данные

В качестве исходных данный программа использует объектный файл - файл, содержащий набор команд в виде байтов. Данный файл должен быть получен с помощью программы-ассемблера. Однако каждый перед каждым байтом команды обязательно должен быть байт-определитель [01]. Это значит, что следующий байт будет командой, а не адресом для записи в память. Причина этой необходимости - команда ORG, которая произвольно задаёт ячейку памяти, которую будет занимать следующая команда или данные при загрузке в память. По умолчанию данные в память загружаются подряд, без пропусков. Однако при выполнении программы команда ORG не выполняется.

Для того, чтобы отладчик мог определить, какой байт будет означать адрес записи, а какой байт - команду или данные, используется байт-определитель, который принимает значение [00] - если следующий байт - адрес памяти, куда будут загружаться следующие команды, или [01] - если следующий байт - команда или данные. Пример содержимого объектного файла addload.bin (байт-определитель выделен) :


В этой программе сначала задаётся адрес, по которому отладчик должен загружать данные в оперативную память.

Любая программа должна начинаться с адреса (ORG)

Далее следуют байты команд, перед которыми байт-определитель - [01].

Перед любым байтом команды должен присутствовать байт [01]

В конце программы - байт [00], однако он не обязателен, только для логичности вида программы.

При несоблюдении этих правил при формировании объектного файла, программа будет выполняться некорректно. Формирование, редактирование и приведение в правильный вид объектного файла - задача программы-ассемблера.

В результате этих действий, объектный файл преобразуется в набор команд, которые необходимо выполнить процессору.

Выходные данные

В результате выполнения программы (полного или пошагового) мы должны увидеть:

Состояние памяти в определённый момент выполнения программы ;

Значение регистров в определённый момент выполнения программы;

Значение СЧАК в определённый момент выполнения программы;

Значение Регистра Команд в определённый момент выполнения программы;

Значение Флагов в определённый момент выполнения программы;

А так же мы должны знать (в случае пошагового выполнения), выполнена ли программа или остались ещё невыполненные команды.

5. Разработка программы

Необходимо разбить программу на подзадачи (для упорядочивания кода).

Считывание объектного файла

Процесс записи данных в память

Процесс выполнения программы

Арифметически-логические операции

Интерфейс (Вывод данных, действия пользователя)

Считывание объектного файла

Считывание объектного файла - это процесс побайтного считывания данных с целью последующей их обработки. Для считывания можно создать отдельный класс, методы которого будет вызывать основная программа.

Процесс записи данных в память

При считывании данных перед их записью в память необходима моментальная обработка - а именно :

Определение типа байта - команда(данные) или адрес.

Определение адреса, куда запишется следующий байт.

Запись только значимых байтов - байты-определители и адреса в память не записываются

Непосредственно запись байтов в оперативную память

Необходимо предусмотреть ошибочную ситуацию, когда память выходит за пределы допустимой (СЧАК >=256)

Процесс выполнения программы

Если в памяти есть невыполненные команды - выполнять их. Выполнение команд происходит по алгоритму:

берётся очередной байт

определяются первые 4 бита. Эти биты соответсвуют командам

в зависимости от команды:

однобайтная - определяются остальные биты, если надо. 5-6 и 7-8 биты соответствуют регистрам. В зависимости от команды, эти биты могу использоваться, а могут игнорироваться

двухбайтная - определяются остальные биты первого байта, как в случае с однобайтной командой. После чего берётся следующий байт, который будет являться адресом или константой, в зависимости от команды. Используются все биты этого байта.

проверяется, есть ли следующий байт в памяти. Если да, то возврат к первому пункту алгоритма

Пример структуры однобайтной команды:


В регистр A заносится сумма значений регистра A и B.

Пример структуры двухбайтной команды:


В ячейку памяти 8А заносится значение регистра D.

Арифметическо-логичесткие операции

Если одна из очередных команд - сложение, побитовое И, ИЛИ или инверсия, то операция выполняется в АЛУ, куда передаются два (или один, в случае инверсии) операнда. В АЛУ производится операция, получается результат, формируются флаги.

Как формируются флаги :

Переполнение - сравнивается знак одного из аргументов и результат. Если они различны, то флаг true. Иначе false.

Отрицательность - выделяется знаковый бит числа (первый слева). Если единица - то флаг true. Иначе false

Ноль - число сравнивается с нулём.

Интерфейс

Интерфейс должен отображать текущее состояние всех элементов процессора, а так же реагировать на действия пользователя - загрузка нового файла, запуск программы, пошаговое выполнение программы. Во избежание ошибок, необходимо предупредить все ошибочные ситуации:

Файла не существует, нет доступа итд. Вывести сообщение об ошибке

Файл ещё не загружен. Кнопки запуска должны быть заблокированы

Программа выполнилась полность. Кнопки запуска заблокированы

Запретить изменение ячеек таблицы, регистров и остальных элементов

Для отображения памяти использовать таблицу 16х16.

Для отображение значения регистров, флагов, СЧАК и Регистра Команд - текстовые поля.

Для определения этапа выполнения программы(выполнена или остались ещё команды) - доступность кнопок выполнения. Если программа выполнена полностью и не осталось команд, кнопки должны стать недоступными. Окончательный вид интерфейс принял :


Краткий алгоритм работы программы :


. Описание программы

ассемблер программа микропроцессор компиляция

Программа состоит из 6 классов:

Main

GUI

-ALU

RON

RAM

Reader

Класс Main

Класс Main - главный класс программы. Содержит метод public static void main, который инициализирует программу.

Класс Main содержит 3 метода и 1 внутренний класс с конструктором.

Поля класса :

S4AK - поле типа int, для реализации СЧАК

comReg - поле типа int, для реализации Регистра Команд

FirstLine - поле типа int, служит для хранения адреса стартовой команды программы

myRAM - поле типа RAM. Реализовывает оперативную память. В конструктор передаётся объём памяти - 256.

myALU - объект типа ALU. Содержит методы арифметическо-логичского устройства. Объект создан для наглядности вызова методов и удобной отладки.

myRON - поле типа RON. Реализовывает регистры.

Temp - переменная типа int, в неё заносятся текущие байты, и из неё выделяются нужные части байта - полбайта команды, четверть байта - регистры, и т. д.

Методы:

-main - запускает методы класса GUI для прорисовки интерфейса

-insert - метод для считывания и записи байтов в память. Вызывает методы считывания файла, поэтому может выбросить IOException. Принцип работы - пока байт не равен -1, считываем, записываем в ячейку памяти соответствующую СЧАК, инкремент СЧАК-а. Определяется точка входу в программу - FirstLine. Регистры, СЧАК - обнуляются. Метод возвращает объект типа RAM, т.к при загрузке изменяется только оперативная память.

- execute - собственно, метод, выполняющий команды. Принцип работы

) Считать байт

) Получить полбайта - команду (байт >> 4), занести в регистр команд

) В соответствии с командой выполнить действие. При считывании следующей команды СЧАК увеличиваем на 1. для выделения оставшейся половины байта (справа) - поразрядное И (байт & 15)

) Если есть байты для считывания, вернуться в первый пункт

Внутренний класс Result нужен для создания объектов типа Result, куда заносятся разные виды данных - объекты , переменные. При создании передаются параметры RAM, RON, флаги, СЧАК, Регистр Команд. Объект нужен для его использования в интерфейсе (является, своего рода «посылкой» для интерфейса с удобным способом извлечения данных). Метод execute возвращает объект типа Result.

Класс GUI

Класс GUI служит для прорисовки интерфейса, отображения и обновления данных, и для реакции на действия пользователя.

В классе GUI прорисовываются элементы интерфейса программы:

-upload, execute, step - Jbutton

Обычные надписи - Jlabel

-Флаги, Регистры, СЧАК, Регистр Команд - JTextField

редактируемое поле имени файла - JTextField

память - таблица JTable

На кнопки добавляются обработчики событий (addEventListener), который вызывают методы класса Main соответственно. Кнопка step запускаем метод execute класса Main 1 раз, а кнопка execute запускает в цикле, пока метод не вернёт null значение.

Так же в этом классе обрабатывается исключение IOException, которое возникает в случае ошибки при чтении файла (например, FileNotFound). В поле, где было введено имя запрашиваемого файла, появляется текст «Error»

Класс ALU

Класс ALU выполняет арифметическо-логические операции, а именно :

сложение

поразрядное И

поразрядное ИЛИ

инверсия

В методы класса передаются параметры типа int - операнды, или операнд (инверсия). Методы возвращают результат типа int. Так же методы формируют флаги, к которым можно получить доступ через методы геттеры : FlagZ(), FlagOv(), FlagN(). Методы этого класса вызываются из метода execute класса Main при выполнении команды. Они возвращают результат и формируют флаги.

Классы RAM, RON и Reader Класс RAM необходим для создания объекта типа RAM с необходимыми полями - массив чисел , длиною 256. С помощью геттеров и сеттеров считываются и задаются данные по необходимому адресу.

Методы :(int address) - возвращает содержимое ячейки памяти по указанному адресу(int address, int value) - заносит значение в ячейку памяти по адресу() - возвращает объём памяти (длина массива)

Класс RON необходим для создания объекта типа RON с необходимыми полями - числами R1, R2, R3, R4 что соответствуют регистрам A, B, C, D. С помощью геттеров и сеттеров считываются и задаются данные необходимого регистра.

Методы :

get(int R) - возвращает значение регистра. Предусмотрен вариант, если вызван несуществующит регистр - вернёт 0

set(int R,int value) - устанавливает значение регистра.

Класс Reader - для побайтового чтения данных из файла. В его метод передаётся параметр имени файла.

. Отладка и тестирование

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

Пример 1 (команды ADD и MOV, файл addmov.bin)

ORG 10h;A, 10h;B, 0Fh;

ADD A, B

Объектный файл :


Результат


Пример 2(команды LOAD и ADD, addload.bin)

ORG 11h;A, 16h;A, 16h;16h;07h;

END;

Объектный файл :


Результат :


Пример 3 (команды MOV и AND)

ORG 10hA, 03h;B, 04h;A, B;

Объектный код :


Результат :


Пример 4 (команды MOV и OR)

ORG 10h;A, 03h;B, 04h;B, A;;

Объектный код :


Результат :


Пример 5 (Команды NOT и MOV)

ORG 10h;A, 03h;A;

END;

Объектный код :


Результат :


Пример 6 (команды MOV и STORE)

ORG 10h;D, FF;

STORE D, 15h;;

Объектный код :


Пример 7 (команда JMP)10h;

JMP 23h;23h;C, 7D;

END

Объектный код:


Результат :


Пример 8 (JO)10h;A, FC;B, 0D;A, B;30h;30h;C DDh;

END;

Объектный код :


Результат :


Пример 9 (JZ)10h;A, 08h;B, 07h;A,B;30h;30h;C, 24h;

END;

Объектный код :


Результат :


Пример 10 (JL)10h;A, DDh;B, 02h;A,B;30h;30h;C, 09h;

END;

Объектный код :


Результат :


Пример 11 (JNZC)10h;A, 09h;A, 20h;20h;

MOV B, 10h;;

Объектный код :


Результат :


Пример 12 (CLF)15h;A, DD;B, EE;A, B;

CLF;;

Объектный код :


Пример 13 (CALL и RET)15h;30h;A, B;30h;B, 08h;

RET;;

Объектный код :


Результат :


Заключение

Как видно из тестовых примеров, данная часть курсового проекта работает в соответствии с заданной структурой ЭВМ. Следовательно. можно сделать вывод, что задание на проект выполнено успешно.

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

Следует заметить, что при программировании реальных процессоров и ЭВМ, средства программиста ограничиваются. Этот недостаток необходимо преодолевать творческим подходом и нестандартным видением задачи.

Библиографический список

1.Ассемблер. [Электронный ресурс] #"577494.files/image035.gif">

Приложение Б

Текст программы

. Класс Main

import java.io.*;Main {

int oper;

static int comReg;

static int S4AK;

static int FirstLine;

static RAM myRAM = new RAM(256);

static ALU myALU = new ALU() ;

static int Temp;

static RON myRON = new RON();

public static RAM insert(String FileName) throws IOException {

S4AK=0;

for(int i=0;i<myRAM.getSize();i++) {

myRAM.set(i,0);

}

Reader file = new Reader(FileName);

while (((Temp=file.nextByte())!=-1) && (S4AK<256)) {

if(Temp==0) {

if(S4AK==0) {

S4AK=file.nextByte();

FirstLine=S4AK;

} else {

S4AK=file.nextByte();

}

} else {

myRAM.set(S4AK, file.nextByte());

S4AK++;

}

}

myRON.set(0,0);

myRON.set(1,0);

myRON.set(2,0);

myRON.set(3,0);

S4AK=FirstLine;

return myRAM;

}static void main(String[] args) throws IOException {

GUI gui = new GUI();

gui.setVisible(true);

}static Result execute() {halfByte=0;

if(((Temp=myRAM.get(S4AK))!=0) && (S4AK<256)) {

halfByte=Temp&15;

switch(comReg=(Temp>>4)) {0: myRON.set(halfByte>>2, myALU.ADD((myRON.get(halfByte>>2)),

myRON.get(halfByte&3)));

S4AK++;

break; //ADD R1 R21: myRON.set(halfByte>>2, myALU.ADD(myRON.get((halfByte>>2)),

(myRAM.get(myRAM.get(++S4AK)))));

S4AK++;

break; // ADD R1 RAM2: myRON.set(halfByte>>2, myALU.AND(myRON.get((halfByte>>2)),

myRON.get((halfByte&3))));

S4AK++;

break; // AND3: myRON.set(halfByte>>2, myALU.OR(myRON.get((halfByte>>2)),

myRON.get((halfByte&3))));

S4AK++;

break; // OR

case 4:

myRON.set(halfByte>>2,myALU.NOT(myRON.get((halfByte>>2))));

S4AK++;

break; // NOT5: myRON.set(halfByte>>2, (myRAM.get(++S4AK)));

S4AK++;

break; // MOV6: myRON.set(halfByte>>2, (myRAM.get(myRAM.get(++S4AK))));

S4AK++;

break; // LOAD7: myRAM.set(myRAM.get(++S4AK), myRON.get((halfByte>>2)));

S4AK++;

break; //STORE8: S4AK=myRAM.get(++S4AK);

break; //JMP9: if(myALU.FlagZ()) {

S4AK=myRAM.get(++S4AK);

} else {

S4AK++;

}

break; //JZ

case 10: if(myALU.FlagOv()) {

S4AK=myRAM.get(++S4AK);

} else {

S4AK++;

}

break; // JO11: if(myALU.FlagN()) {

S4AK=myRAM.get(++S4AK);

} else {

S4AK++;

}

break; // JL

case 12: int x=myRON.get((halfByte>>2));

if(x!=0) {

myRON.set((halfByte>>2), (--x));

S4AK=myRAM.get(++S4AK);

} else {

S4AK++;

}

break; // JNZC13: myALU.setFlags((1));

S4AK++;

break; // CLF

case 14: myRON.set(3, (S4AK+2));

S4AK=myRAM.get(S4AK+1);

break; // CALL

case 15: S4AK=myRON.get((3));

break;

default:System.out.println(1); S4AK++; ;

}

} else {return null;}

return new Result(myRAM, myRON, ALU.FlagN(), ALU.FlagZ(), ALU.FlagOv(), S4AK, comReg);

}

}

class Result {

int comReg;

int S4AK;

RAM myRAM;

RON myRON;

boolean flagZ;

boolean flagN;

boolean flagOv;

Result(RAM myRAM,RON myRON, boolean flagN, boolean flagZ, boolean flagOv, int S4AK, int comReg) {

this.myRAM=myRAM;

this.myRON=myRON;

this.flagN=flagN;

this.flagZ=flagZ;

this.flagOv=flagOv;

this.S4AK=S4AK;

this.comReg=comReg;

}

}

. Класс GUIjava.io.*;java.awt.*;javax.swing.*;java.awt.event.*;class GUI extends JFrame {

public GUI() {

super();

this.setSize(660,375);

this.getContentPane().setLayout(null);

JPanel jPanel1 = new JPanel();

JPanel jPanel2 = new JPanel();

JLabel jLabel= new JLabel();

jLabel.setText("Binary file:");

jLabel.setSize(60,20);

JLabel jRegs= new JLabel();

jRegs.setText("Registers:");

jRegs.setSize(60,20);

JLabel jA= new JLabel();

jA.setText("A");

jA.setSize(20,20);

JLabel jB= new JLabel();

jB.setText("B");

jB.setSize(20,20);

JLabel jC= new JLabel();

jC.setText("C");

jC.setSize(20,20);

JLabel jD= new JLabel();

jD.setText("D");

jD.setSize(20,20);

JLabel flags= new JLabel();

flags.setText("Flags:");

flags.setSize(60,20);

JLabel jN= new JLabel();

jN.setText("fN");

jN.setSize(20,20);

JLabel jZ= new JLabel();

jZ.setText("fZ");

jZ.setSize(20,20);

JLabel jOv= new JLabel();

jOv.setText("fOv");

jOv.setSize(20,20);

JLabel s4= new JLabel();

s4.setText("S4");

s4.setSize(20,20);

JLabel regC= new JLabel();

regC.setText("rc");

regC.setSize(20,20); JTextField source= new JTextField();

source.setSize(100,20);

source.setText("binary.bin");

final JTextField rA= new JTextField();

rA.setSize(40,20);

rA.setText("");

final JTextField rB= new JTextField();

rB.setSize(40,20);

rB.setText("");

final JTextField rC= new JTextField();

rC.setSize(40,20);

rC.setText("");

final JTextField rD= new JTextField();

rD.setSize(40,20);

rD.setText("");

final JTextField fN= new JTextField();

fN.setSize(40,20);

fN.setText("");

final JTextField fZ= new JTextField();

fZ.setSize(40,20);

fZ.setText("");

final JTextField fOv= new JTextField();

fOv.setSize(40,20);

fOv.setText("");

final JTextField schak= new JTextField();

schak.setSize(40,20);

schak.setText("");JTextField regCom= new JTextField();

regCom.setSize(40,20);

regCom.setText("");

JButton upload = new JButton();

upload.setSize(75,20);

upload.setText("Upload");

final JButton exec = new JButton();

exec.setSize(80,20);

exec.setText("Execute");JButton step = new JButton();

step.setSize(80,20);

step.setText("Step");.setTitle("Title");

String[] column = {"0","1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};

final String[][] dataTable = new String[16][16];JTable jTable = new JTable(dataTable, column);

JScrollPane jScroll= new JScrollPane(jTable);

jScroll.setSize(550,280);

//Locations :::.setLocation(10,10);

source.setLocation(80,10);

upload.setLocation(190,10);

exec.setLocation(275,10);

step.setLocation(360,10);

jScroll.setLocation(10,40);

jA.setLocation(570,40);

jB.setLocation(570,70);

jC.setLocation(570,100);

jD.setLocation(570,130);

jRegs.setLocation(570,10);

rA.setLocation(590,40);

rB.setLocation(590,70);

rC.setLocation(590,100);

rD.setLocation(590,130);

flags.setLocation(570,160);

jN.setLocation(570,190);

jZ.setLocation(570,220);

jOv.setLocation(565,250);

fN.setLocation(590,190);

fZ.setLocation(590,220);

fOv.setLocation(590,250);.setLocation(565,280);

regCom.setLocation(590,280);

s4.setLocation(565,310);

schak.setLocation(590,310);.setEnabled(false);

step.setEnabled(false);

jTable.setEnabled(false);

fN.setEnabled(false);

fZ.setEnabled(false);

fOv.setEnabled(false);

rA.setEnabled(false);

rB.setEnabled(false);

rC.setEnabled(false);

rD.setEnabled(false);

schak.setEnabled(false);

regCom.setEnabled(false);(jLabel);

add(source);

add(upload);

add(exec);

add(step);

add(jScroll);

add(jRegs);

add(jA);

add(jB);

add(jC);

add(jD);

add(regC);

add(s4);

add(regCom);

add(schak);

add(rA);

add(rB);

add(rC);

add(rD);

add(flags);

add(jN);

add(jZ);

add(jOv);

add(fN);

add(fZ);

add(fOv);.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

RAM k=null;

try {

k=Main.insert(source.getText());

} catch (Exception a) {source.setText("Error");}(k!=null) {

for(int i=0;i<16;i++) {

for(int j=0;j<16; j++) {

dataTable[i][j]="0";

dataTable[i][j]=Integer.toHexString(k.get((i*16)+j));

}

}.repaint();

exec.setEnabled(true);

step.setEnabled(true);

}

}

});.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

Result res;=Main.execute();

if(res!=null) {

for(int i=0;i<16;i++) {

for(int j=0;j<16; j++) {

dataTable[i][j]="0";

dataTable[i][j]=Integer.toHexString(res.myRAM.get((i*16)+j));

}

}

String A=res.myRON.get(0)>127 ? "-"+(256-res.myRON.get(0)) : Integer.toString(res.myRON.get(0));

String B=res.myRON.get(1)>127 ? "-"+(256-res.myRON.get(1)) : Integer.toString(res.myRON.get(1));

String C=res.myRON.get(2)>127 ? "-"+(256-res.myRON.get(2)) : Integer.toString(res.myRON.get(2));

String D=res.myRON.get(3)>127 ? "-"+(256-res.myRON.get(3)) : Integer.toString(res.myRON.get(3));

String R=Integer.toString(res.comReg);

String S=Integer.toString(res.S4AK);

rA.setText(A);

rB.setText(B);

rC.setText(C);

rD.setText(D);

schak.setText(S);

regCom.setText(R);.setText(Boolean.toString(res.flagZ));

fN.setText(Boolean.toString(res.flagN));

fOv.setText(Boolean.toString(res.flagOv));

jTable.repaint();

} else { exec.setEnabled(false); step.setEnabled(false);}

}

});.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

Result res; ((res=Main.execute())!=null) {

for(int i=0;i<16;i++) {

for(int j=0;j<16; j++) {

dataTable[i][j]="0";

dataTable[i][j]=Integer.toHexString(res.myRAM.get((i*16)+j));

}

}

String A=res.myRON.get(0)>127 ? "-"+(256-res.myRON.get(0)) : Integer.toString(res.myRON.get(0));

String B=res.myRON.get(1)>127 ? "-"+(256-res.myRON.get(1)) : Integer.toString(res.myRON.get(1));

String C=res.myRON.get(2)>127 ? "-"+(256-res.myRON.get(2)) : Integer.toString(res.myRON.get(2));

String D=res.myRON.get(3)>127 ? "-"+(256-res.myRON.get(3)) : Integer.toString(res.myRON.get(3));

String R=Integer.toString(res.comReg);

String S=Integer.toString(res.S4AK);

rA.setText(A);

rB.setText(B);

rC.setText(C);

rD.setText(D);

schak.setText(S);

regCom.setText(R);

fZ.setText(Boolean.toString(res.flagZ));

fN.setText(Boolean.toString(res.flagN));

fOv.setText(Boolean.toString(res.flagOv));

jTable.repaint();

} exec.setEnabled(false); step.setEnabled(false);

}

});

}

}

. Класс ALUclass ALU {

private static boolean flagN, flagZ, flagOv;void setFlags(int R1, int R2, int R) {

flagOv = (((R1&128)==128) && ((R&128)==0))||(((R2&128)==128) && ((R&128)==0));

flagN = (R & 128)==128;

flagZ = R==0;

}void setFlags(int R) {

flagN = (R & 128)==128;

flagZ = R==0;

}ALU() {

flagN=flagZ=flagOv=false;

}int ADD(int R1, int R2) {

setFlags(R1&0xff,R2&0xff,(R1+R2));

return (R1+R2)&0xff;

}int AND (int R1,int R2) {

setFlags(R1, R2, (R1&R2));

return (R1&R2);

}int OR (int R1,int R2) {

setFlags(R1, R2, (R1|R2));

return (R1|R2);

}int NOT (int R) {

setFlags((~R));

return ~R&0xFF;

}static boolean FlagZ () { return flagZ;}

public static boolean FlagN () { return flagN;}static boolean FlagOv () { return flagOv;}

}

. Класс RAMclass RAM {

private int Memory[];

public RAM(int MemorySize) {

Memory=new int[MemorySize];

}

public int get(int address) {

return Memory[address];

}

public void set(int address, int value) {

Memory[address]=value;

}

public int getSize() {

return Memory.length;

}

}

. Класс RONclass RON {

private int R1, R2, R3, R4;

public RON() {

R1=0;

R2=0;

R3=0;

R4=0;

}

public int get(int R) {

switch (R) {

case 0: return R1;

case 1: return R2;

case 2: return R3;

case 3: return R4;

default: return 0;

}

}

public void set(int R,int value) {

switch (R) {

case 0: this.R1=value; break;

case 1: this.R2=value; break;

case 2: this.R3=value; break;

case 3: this.R4=value; break;

default: ;

}

}

}

. Класс Readerjava.io.*;class Reader {

RandomAccessFile reader;

public Reader(String FileName) throws IOException {

try {

reader = new RandomAccessFile(FileName, "r");

} catch (IOException e) {}

reader.seek(0); }

public int nextByte() throws IOException {

int Temp;

Temp=(reader.read());

return Temp;

}



Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!