Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Когда в стеке вычислений два числа, операция запускается.
private uint _plusValue;
public uint Get()
{
uint result = _plusValue;
_plusValue = 0;
return result;
}
public void Set(uint value)
{
_plusValue += value;
}
Как различается нулевое и обнулённое значение?
Число регистров - 2^k (k должно быть не менее 3, наверное :)
(к ним также относится счётчик команд ip)
Архитектура - трехадресная
Число команд - одна единственная (условное вычитание)
Число флагов - один (f - флаг переполнения)
Разрядность машинного слова - 2+3*k
Максимально адресуемое число ячеек памяти - 2^(2+3*k)
Все обрабатываемые числа считаются положительными,
-1=11...1111 - максимальное число
Формат команды:
тип
00 R1 R2 R3 - csub R1,R2,R3 if f=0 then R1:=R2-R3,f:=R3>R2 else f=0
01 R1 R2 R3 - csub R1,R2,[R3] if f=0 then R1:=R2-[R3],f:=[R3]>R2 else f=0
10 R1 R2 R3 - csub R1,[R2],R3 if f=0 then R1:=[R2]-R3,f:=R3>[R2] else f=0
11 R1 R2 R3 - csub [R1],R2,R3 if f=0 then [R1]:=R2-R3,f:=R3>R2 else f=0
R1,R2,R3 - поля размером k бит, вся команда занимает одну ячейку памяти
Основной цикл:
Проверить флаг
если f=0
1) считать команду из памяти
2) если тип команды 01 или 10 - считать операнд из памяти
3) вычислить разность и установить флаг при переполнении
4) записать результат в приёмник и увеличить счетчик команд
если он(ip) не является приёмником данной команды
иначе
сбросить флаг
перейти к началу
При включении питания или поступлении сигнала сброса все регистры и флаг
переполнения обнуляются, и начинает выполняться команда расположеная по
нулевому адресу.
Примеры(предполагается что в начале флаг переполнения сброшен)
1) обнуление регистра
csub r,r,r; ;r=0
2) загрузка в регистр единицы
csub r,r,r ;r=0
csub r,ip,r ;r=$(адрес этой команды)
csub r,ip,r ;r=1
3) сложение регистров a и b
csub r,r,r ;r=0
csub b,r,b ;b=-b
csub r,r,r ;при b>0 эта команда не выполяется
csub a,a,b ;a=a-(-b)
csub r,r,r ;при -b>a эта команда не выполяется
4) проверка числа на 0
csub z,z,z
csub z,z,r
csub <- эта команда будет выполнена если r=0
5) загрузка из памяти
csub z,z,z
csub r,[m],z
6) сохранение в памяти
csub z,z,z
csub [m],r,z
7) деление числа в регистре a на число в регистре b, с записью частного в
регистр d и остатка в регистр a
#1 csub z,z,z ;z=0
#2 csub m,ip,z ;m=$
#3 csub m,m,ip ;m=-1
#4 csub z,z,z ;никогда не исполняется
#5 csub d,d,d ;d=0
#6 csub l,ip,m ;l=адрес следующей команды
;начало цикла
#7 csub d,d,m ;d=d-(-1) не исполняется при первом проходе цикла
#8 сsub z,z,z ;исполняется только при первом прохорде
#9 csub a,a,b ;a=a-b
#10 csub ip,l,z ;ip=l-z, то есть переход в начало цикла если в предыдущей
;команде не произошло переполнение
;далее довычисление остатка
#11 csub z,z,b ;z=z-b
#12 csub z,z,z ;на результат предыдущей команды не влияет
#13 csub a,a,b ;формирование остатка
Работа алгоритма:
пусть a=7 и b=3
#1 z=0 f=0
#2 m=2 f=0
#3 m=-1 f=1 -1=11...1111
#5 d=0 f=0
#6 l=7 f=1
#8 z=0 f=0
#9 a=4 f=0
#10 ip=7 f=0
#7 d=1 f=1
#9 a=1 f=0
#10 ip=7 f=0
#7 d=2 f=1 частное уже вычислено
#9 a=-2 f=1 -2=11...1110
#11 z=-3 f=1 -3=11...1101
#13 a=1 f=0 остаток тоже вычислен
2. Не понятно, зачем нужен стек на 16 слов, если есть 19 неиспользуемых регистров.
Periwinkle: процессор с одной инструкцией