Я читаю и изучаю Элементы вычислительных систем но я застрял в одном месте. Образец главы, пропустив следующие 5 инструкций, можно найти здесь.
В любом случае, я пытаюсь реализовать виртуальную машину (или байтовый код для транслятора сборки), но я застрял в том, чтобы пропустить следующие 5 инструкций на один пункт.
Обозначение сборки можно найти здесь.
Цель состоит в том, чтобы реализовать транслятор, который будет переводить определенный байтовый код в этот ассемблерный код.
Пример, который я сделал успешно, - это байтовый код
push constant 5
который переводится на:
@5
D=A
@256
M=D
Как я уже сказал, ассемблер для Hack можно найти в предоставленной мной ссылке, но в основном:
@5 // Load constant 5 to Register A
D=A // Assign the value in Reg A to Reg D
@256// Load constant 256 to Register A
M=D // Store the value found in Register D to Memory Location[A]
Что ж, это было довольно просто. По определению ячейка памяти 256 является вершиной стека. Так
push constant 5
push constant 98
будет переведен на:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
что все в порядке ..
Еще хочу привести еще один пример:
push constant 5
push constant 98
add
переводится на:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
@257 // Here starts the translation for 'add' // Load top of stack to A
D=M // D = M[A]
@256 // Load top of stack to A
A=M // A = M[A]
D=D+A
@256
M=D
Я думаю, это довольно ясно.
Однако я понятия не имею, как я могу перевести байтовый код
eq
к сборке. Определение для эквалайзера выглядит следующим образом:
Три команды (eq, gt, lt) возвращают логические значения. VM представляет истину и ложь как ????-1 (минус один, 0xFFFF) и 0 (ноль, 0x0000) соответственно.
Поэтому мне нужно вставить два значения в регистры A и D соответственно, что довольно просто. Но как мне создать ассемблерный код, который будет проверять значения и нажимать 1, если результат истинный, или 0, если результат ложный?
Ассемблерный код, поддерживаемый для Hack Computer, выглядит следующим образом:
Я могу сделать что-то вроде:
push constant 5
push constant 6
sub
который будет содержать значение 0, если 2 значения, помещенные в стек, равны или! 0, если нет, но как это поможет? Я пробовал использовать D&A или D&M, но это тоже мало помогло ..
Я также могу ввести условный переход, но как мне узнать, к какой инструкции перейти? В коде сборки взлома нет чего-то вроде «пропустить следующие 5 инструкций» и т. Д.
[edit by Spektre] сводка целевой платформы, как я ее вижу
- 16-битная архитектура фон Неймана (адрес 15 бит с доступом к тексту 16 бит)
- Память данных 32кВт (чтение / запись)
- Память инструкций (программ) 32кВт (только чтение)
- собственные 16-битные регистры A, D
- 16-битные регистры общего назначения R0-R15, отображаемые в память данных по адресу 0x0000 - 0x000F
- они, скорее всего, также используются для:
SP(R0),LCL(R1),ARG(R2),This(R3),That(R4)
- Экран отображается в памяти данных по адресу 0x4000-0x5FFF (512x256 ч / б пикселей, 8 кВт)
- Клавиатура сопоставлена с памятью данных по адресу 0x6000 (код ASCII при последнем нажатии клавиши?)
Z,C
, а некоторые также включают условные переходы (в основном MCU). Таким образом,cmp a,b
обычно выполняетa-b
, но отбрасывает результат и оставляет только флаги. А теперь войдите в состояние (неважно, в прыжке или какой-либо другой инструкции)equal=(Z), greater=(NC),lower(C)
- person Spektre   schedule 11.05.2015ADC,SBC
, который+.-
сCarry
, а также вы можете обычно сдвигатьZero
в положениеCarry
, чтобы использовать это также для равного ... Таким образом, нет нужен прыжок - person Spektre   schedule 11.05.2015SP
и счетчика программPC
? регистры состояния, такие как флаги ..., а не только аккумуляторa
и регистр общего назначенияb
- person Spektre   schedule 11.05.2015SP
находится в ОЗУ по адресу 0 и имеет длину 1 БАЙТ, поэтому стек составляет 256 БАЙТОВ и находится бог знает где (возможно, 0xFE00 ... 0xFFFF), поэтому ваша инструкция push pop неверна, вам нужно прочтите SP и используйте это как целевое расположение стека ... - person Spektre   schedule 11.05.2015push value
обычно делается так:dec SP; mov [SP],value;
иpop value
вроде:mov value,[SP]
; inc SP; `стек может расти в обоих направлениях (x86 растет вниз, но есть процессоры, которые растут). в вашей жестко закодированной реализации push / pop вы не могли бы сделать что-то вродеfor (i=0;i<n;i++) push i;
в случае, еслиn
является переменной, что является довольно распространенным случаем - person Spektre   schedule 11.05.2015SP,ARG,...
- это определенные области памяти в памяти данных и имеют особое значение в вашей архитектуре ... попробуйте выяснить, что они означают - person Spektre   schedule 11.05.20155.2 The Hack Hardware Platform Specification
, где с самого начала прямо указано, что платформа имеет 2 области памяти RAM (память данных) и ROM (память инструкций). Также для архитектуры фон Неймана (см. I8051 и клоны) регистры GP и (иногда даже все регистры) отображаются в пространство памяти данных ... Итак: 1. вы не можете делать самомодифицирующийся код 2. или напрямую обращаться к регистру ПК, следовательно, это дрянная архитектура, неспособная выполнить инструкцию вызова (ret, push , pop возможны), и это приводит к невозможности ничего кодировать ... - person Spektre   schedule 13.05.2015anything
- неправильное слово, вместо этого должно бытьeverything
(в конце последней рекомендации) извините, но мой английский не очень хорош .... и в довершение всего добавьте отсутствие доступа к флагам ALU, что безумие - person Spektre   schedule 13.05.2015