Радуют меня подобные находки. Искал одну инфу, а наткнулся на другое - учебный процессор. Вракипедия ничего внятного не сказал об опкодах, но старик Google подсказал ссылки на симулятор-ассемблер и на инфу о программировании. Отложил знакомство на следующий день, собрал нужную инфу, запустил редактор.
Команд процессора немного - загрузка значений регистров R0-R7, запись регистров в память, вызов процедур и прерываний,условные/безусловные переходы, арифметические операции - ADD, бинарные - NOT/XOR.
С этим списком я стал писать первую программу, которая напечатает 16-битное число:
.ORIG x3000
LD R1,NUMB ; load register from memory - number
LD R2,CNT ; counter
CONV LD R0,ZRO ; ascii number "0"
AND R1,R1,R1 ; test if positive
BRN INCR0 ; if yes change code to "1"
BR NOBIT
INCR0 ADD R0,R0,1
NOBIT
OUT ; print character (R0=code)
ADD R1,R1,R1 ; shift left
ADD R2,R2,-1 ; decrement xounter
BRp CONV ; end of iteration: branch if R2 >0(p-Positive)
HALT ; stop executiom
NUMB .FILL x83AA
CNT .FILL x10
ZRO .FILL x30
.END
LD R1,NUMB ; load register from memory - number
LD R2,CNT ; counter
CONV LD R0,ZRO ; ascii number "0"
AND R1,R1,R1 ; test if positive
BRN INCR0 ; if yes change code to "1"
BR NOBIT
INCR0 ADD R0,R0,1
NOBIT
OUT ; print character (R0=code)
ADD R1,R1,R1 ; shift left
ADD R2,R2,-1 ; decrement xounter
BRp CONV ; end of iteration: branch if R2 >0(p-Positive)
HALT ; stop executiom
NUMB .FILL x83AA
CNT .FILL x10
ZRO .FILL x30
.END
Дальнейшие занятия оставил на вечер, потому что меня смутило отсутствие арифметических сдвигов. Нет, один из сдвигов можно зачесть - ADD равносилен сдвигу влево. Поискал примеры кода сдвига вправо, наткнулся на тред. Нет, слишком замудрено, напишу свое. Вышло 32 байта, которое проще предложенных вариантов:
.ORIG x3000
LD R0,VAL ;value
AND R1,R1,0 ;bit weight #1
ADD R1,R1,1 ;1
AND R2,R2,0 ;bit weight #2
ADD R2,R2,2 ;2
AND R3,R3,0 ; new Value
SHRL ADD R4,R0,0
AND R4,R4,R2; R4&R2
BRz NOBIT
ADD R3,R3,R1
NOBIT
ADD R1,R1,R1
ADD R2,R2,R2
BRZ EXLP
BR SHRL
EXLP
HALT
VAL .FILL x83AA
.END
Наверное, код можно исправить, спишу на то, что только изучаю. Думаю, что удобнее AND R4,R0,R2
Теперь я решил вернуться к печати шестнадцатиричных чисел, которая мне показалась не такой уж простой. Для простоты написал циклический сдвиг влево:
.ORIG x3000
LD R1,VAL ;value
LD R2,C4 ; 4 digits
HLP
;cyclic shift
LD R3,C4
CSLP
AND R1,R1,R1
BRn SETBIT
ADD R1,R1,R1
BR NXTC
SETBIT ADD R1,R1,R1
ADD R1,R1,1
NXTC ADD R3,R3,-1
BRp CSLP
;digit output
AND R0,R1,15
LEA R4,HN
ADD R4,R0,R4
LDR R0,R4,0
OUT
;
ADD R2,R2,-1
BRp HLP
HALT
C4 .FILL 4 ; counter
VAL .FILL x83AA
HN .STRINGZ "0123456789ABCDEF"
.END
Очередной успех! Я начал думать над другими задачами, но отложил разработку на время.
Мне было неясно, как использовать некоторые операции с учетом существующих команд.
Например, бинарное OR. Один из доков подсказал : A OR B = NOT[(NOT A) AND (NOT B)]
исключающее ИЛИ решается другим методом.
С утра придумал задачку, но не решил, как реализовать сравнение чисел. Вычитанием же - A-B==A+(-B), а -B вычисляется как NOT.
Дополнение. Вечером стал кодить программу смены регистра:
.ORIG x3000
LEA R0,TX
PUTS
UC
LDR R1,R0,0
LD R2,C97
NOT R2,R2
ADD R2,R2,R1
BRn NXT
LD R2,C122
NOT R2,R2
ADD R2,R2,R1
BRp NXT
PUT LD R2,C32
NOT R2,R2
ADD R1,R1,R2
STR R1,R0,0
NXT ADD R0,R0,1
LDR R2,R0,0
AND R2,R2,R2
BRz EXLP
BR UC
EXLP
LEA R0,TX
PUTS
HALT
;97-a,122-z
C32 .FILL 31
C97 .FILL 96
C122 .FILL 121
TX .STRINGZ "this is a tezt1234567890ABCD\n"
.END
Тут обнаружился один нюанс: NOT R2,R2 дает результат -R2-1, это видно в отладчике. Думал, что на этом остановлюсь, хотелось бы порисовать, но в консоли не особо развернешься. Внезапно обнаружил PennSim версии венды, а не убогой Java. Попробую с ним поиграть.
Программа+исходники. shr_22 это оптимизированный код. Если задуматься, то можно использовать другой сдвиг на заданное количество.
Комментарии
Отправить комментарий