Почему моя программа сборки не устанавливает правильное значение r1?

Я пишу программу сборки на машине LC3.

Моя программа сборки представляет собой программу LC3, которая умножает R2 и R3 и сохраняет результат в R1.

Вот мой исходный код (с комментариями)

;Sets pc to this address at start of program 
.ORIG x3000
;R1 will store the result lets clear it(ANd with 0)
AND R1,R1,x0
;R2 will be multiplied by R3, let's clear both of them 
AND R2,R2,x0
AND R3,R3,x0
;Test case 4 * 3 = 12;
ADD R2,R2,4
ADD R3,R3,3
;Add to increment zone 
LOOP Add R1,R1,R2;
;Decrement the counter, in this case the 3 or R3
ADD R3,R3,x-1
BrP LOOP
HALT
.END

Мой тестовый пример умножает 4 * 3. Результат должен быть 12, и он должен храниться в R1. Однако, когда я запускаю эту программу в симуляторе LC3, вот что я получаю на выходевведите здесь описание изображения

R3 содержит правильное значение в конце, но R1 содержит -1... Кто-нибудь видит проблему с моим кодом? Я обязательно очистил R1 в начале и продолжал добавлять R3 к R1 и сохранять результат в R1, пока счетчик R3 или 3 в этом случае больше нуля.


person committedandroider    schedule 17.04.2015    source источник
comment
Я просто запускаю вашу программу, и это не то, что я получаю. Где вы поставили точку останова? Вы должны поставить его на инструкцию HALT. В противном случае ваши значения могут быть перезаписаны ловушкой HALT.   -  person m0skit0    schedule 17.04.2015
comment
Также обратите внимание, что вы не используете R2 нигде в своем цикле.   -  person m0skit0    schedule 17.04.2015
comment
Разве точка останова не предназначена только для отладки? Зачем ставить точку останова на инструкции HALT? Разве HALT уже не останавливает программу?   -  person committedandroider    schedule 18.04.2015
comment
Я исправил свой R2, чтобы убедиться, что результат R1 + R2 сохраняется в R1. Теперь это выглядит хорошо?   -  person committedandroider    schedule 18.04.2015
comment
HALT не останавливает ЦП в симуляторе, который у меня есть, на самом деле это псевдоинструкция (TRAP HALT). Это обучающая машина, она не дает каких-либо реальных полезных результатов, поэтому, чтобы проверить, работает ли ваша программа нормально, вам нужно либо остановить ее до ее завершения, либо где-то распечатать результаты.   -  person m0skit0    schedule 18.04.2015
comment
Да, спасибо, что разъяснили это. en.wikipedia.org/wiki/HLT говорит, что HALT останавливает ЦП. Сбивает с толку. Но знаете ли вы, в чем проблема с моей программой? Я поставил остановку на TRP, и он все равно выдал этот результат, R1 на -1?   -  person committedandroider    schedule 18.04.2015
comment
Эта инструкция HLT предназначена для x86, а не для LC3. Каждая архитектура отличается. Опять же, если вы выполните HALT, ваши регистры будут испорчены кодом программного прерывания. Вы можете проверить, что делает HALT, шаг за шагом выполняя свою программу, и вы увидите, как она переходит к другому коду.   -  person m0skit0    schedule 18.04.2015
comment
Выдает ли эта обновленная программа правильный результат в вашей симуляции?   -  person committedandroider    schedule 18.04.2015
comment
Это вам решать, так вы научитесь пользоваться симулятором.   -  person m0skit0    schedule 18.04.2015
comment
Спасибо, что заставил меня есть овощи :)   -  person committedandroider    schedule 18.04.2015
comment
Что вы подразумеваете под псевдоинструкцией? Отсюда en.wikipedia.org/wiki/TRAP_%28processor_instruction%29. , Я читал, что Trap Halt — это процедура, используемая для завершения программ. Как это может испортить регистры? Это должно просто завершить программу. Эта вики-статья была о языке ассемблера LC3.   -  person committedandroider    schedule 18.04.2015


Ответы (1)


HALT — это просто «псевдоинструкция» для инструкции TRAP, используемой для остановки машины.

Вы можете написать:

TRAP x25  ;HALT the machine

Но таким образом вам нужно запомнить позицию в векторе TRAP, в данном случае x25. Так что лучше просто использовать HALT вместо этого.

Другие распространенные TRAP также имеют псевдоинструкции: IN, OUT и т. д.

Я предполагаю, что вы хотите где-то хранить свои результаты. Вы можете сделать что-то вроде:

;Sets pc to this address at start of program 
.ORIG x3000
;R1 will store the result lets clear it(ANd with 0)
AND R1,R1,x0
;R2 will be multiplied by R3, let's clear both of them 
AND R2,R2,x0
AND R3,R3,x0
;Test case 4 * 3 = 12;
ADD R2,R2,4
ADD R3,R3,3
;Add to increment zone 
LOOP Add R1,R1,R2;
;Decrement the counter, in this case the 3 or R3
ADD R3,R3,x-1
BrP LOOP
ST R1, Result         ;STORE R1 at Result
HALT
Result .FILL x0000    ;this will be x000C=12h after execution
.END

-----------------------------------РЕДАКТИРОВАТЬ------------------------- -

Последний вопрос о тебе (в комментариях):

Если HALT остановит мою программу, как тогда будет работать директива Reslt .FILL x0000?

Это больше вопрос о том, как работают ассемблеры.

Ответ: потому что: Время сборки != Время выполнения

Директивы рассматриваются во время сборки.

Фактически время сборки состоит из двух проходов:

  1. Разрешить символы, создав таблицу символов
  2. Преобразуйте инструкции в «действительно исполняемый/машинный код», используя таблицу символов.

Это очень распространенный способ реализации ассемблеров, и ассемблер LC3 не является исключением.

person JosEduSol    schedule 18.04.2015
comment
Разве это не должно хранить результат? ЦИКЛ Добавить R1,R1,R2; Добавить R1 и R2 и сохранить результат добавления данных этих регистров в R1? - person committedandroider; 18.04.2015
comment
@committedandroider В конце вашего LOOP у R1 есть результат. Но... когда вы ОСТАНАВЛИВАЕТЕ машину, вы вызываете специальную процедуру, в которой регистры снова используются, поэтому их содержимое изменяется. - person JosEduSol; 18.04.2015
comment
Что я должен позвонить вместо этого, чтобы содержимое не изменилось? просто .END, а не HALT? - person committedandroider; 18.04.2015
comment
Зачем называть Результат .FILL x0000? Разве вы уже не вызывали ST R1, Result для сохранения регистра в R1? - person committedandroider; 20.04.2015
comment
@committedandroider После HALT инструкций нет. Ваша программа останавливается на HALT, поэтому вам нужен HALT. Result .FILL x0000 — это просто директива для ассемблера РЕЗЕРВИРОВАТЬ некоторое пространство, которое будет использоваться позже во время выполнения, вы можете думать о Result как о переменной, если хотите. Итак... ST R1, Result сохраняет результат в переменной Result. - person JosEduSol; 20.04.2015
comment
Меня смущает изложенная вами логика. Если HALT остановит мою программу, как тогда будет работать директива Reslt .FILL x0000? - person committedandroider; 21.04.2015
comment
@committedandroider Отредактировал мой ответ, чтобы ответить на ваш последний вопрос. - person JosEduSol; 21.04.2015
comment
Спасибо!! Можете ли вы проверить и этот? superuser.com/questions/904324/. Мне нужен ваш опыт в ассемблере :) - person committedandroider; 21.04.2015