Общая структура системы команд MIPS
- Принципы RISC: - отсутствие вычислительно сложных инструкций,
- фиксированная длина инструкции,
- большое количество регистров общего назначения,
- ограничения на работу непосредственно с оперативной памятью как с медленным устройством
 
- …и их реализация в MIPS: - + отсутствие дублирующих инструкций, псевдоинструкции
- + трёхадресность,
- + разделение памяти данных и команд,
- + оптимизация под конвейер (см. далее)
- …
- удобство чтения/написания инструкций ассемблера и неудобство чтения машинного кода человеком (упаковка битов, псевдоинструкции и т. п.) 
- т. н. исключения — нормальное состояние программы, а не ошибка
- некоторые регистры более специальные, чем другие: - $0 всегда равен 0, $31 используется для подпрограмм и т. п. 
 
 
- Организация системы команд MIPS32: - (на лекции не перечисляются все команды, даются только примеры, подбор команд по таблице — это ДЗ) 
- 32 регистра общего назначения, доступа к специализированным регистрам нет (в т. ч. нет регистра флагов, даже на аппаратном уровне!) 
- 3 базовых типа команд биты слова 31…26 25…21 20…16 15…11 10…6 5…0 6 5 5 5 5 6 R-Тип (Register) op rs rt rd sa funct I-Тип (Immediate) op rs rt immediate J-Тип (Jump) op target - op — код операции (6 битов) 
- rs — № регистра-источника (5 битов) 
- rt — № регистра-опреанда (для команд типа I — регистра-назначения) (5 битов) 
- immediate — непосредственный знаковый операнд (16 битов), используется для логических операндов, арифметических знаковых операндов, для смещений в адресе загрузки/сохранения, для команд условного ветвления («близкого» перехода) 
- target — адрес перехода (26 битов); в действительности это 28 битов без последних 2, т. к. адрес перехода всегда кратен 4 (то же верно и для «близкого» перехода, 18 битов вместо 16) 
- rd — № регистра-назначения (5 битов) 
- sa — величина сдвига для команд побитового сдвига регистра (5 битов достаточно  ) )
- funct — поле функции (6 битов), используется для разных команд, у которых код операции одинаковый. Например, все команды типа R, кроме работающих с сопроцессором, имеют opcode=0 (SPECIAL), а различаются полем funct. По-видимому, для эффективной реализации R-команд в конвейере удобнее не декодировать опкод, а по-быстрому сравнить его с нулём, и получать значения регистров, параллельно декодируя функцию, чтобы потом её применить. 
 
- Знаковая и беззнаковая арифметика; регистры LO/HI для умножения/деления; побитовые операции - Для некоторых операций (например, сложения) «знаковость» означает, что при переполнении будет возникать исключение, а «беззнаковость» — что не будет.
 
- Условная пересылка и сравнение - сравнение только с 0 или = / ≠, сравнение на > / < двух регистров потребовало бы двух арифметических операций! 
 
- Работа с памятью (в т. ч. псевдоинструкции типа li) 
- Суть понятия псевдоинструкции на примере li регистр, число:   
- Нет никакой инструкции «положить I-число в регистр», зато есть инструкция «сложить I-число с $0 (с нестираемым нулём) и положить результат в регистр» 
- Если число в li больше 16 битов, псевдоинструкция раскладывается в две: - записать старшую половину большого числа (это I-число) в старшую половину регистра (младшая при этом обнуляется),
- побитово добавить (OR) младшую половину большого числа в регистр
 
- Соответственно, программисту не надо в уме прикидывать, влезает ли число в 16 битов, и распиливать его, если не влезает 
- это — наиболее эффективные способы реализации команды li регистр, число 
- Обратите внимание на использование $1 для хранения промежуточных данных 
 
- переходы: короткие (типа I) и длинные (типа J) - Короткие — условные - сравнения бываюто только на = / ≠ и с нулём, остальное — (например, сравнение двух регистров на >/<) — псевдоинструкции:   
 
- (повторение  ) непосредственно указываемый адрес в командах типа I и J усекается на 2 бита справа, потому что они всё равно всегда равны 0, ибо адрес команды всегда кратен 4 ) непосредственно указываемый адрес в командах типа I и J усекается на 2 бита справа, потому что они всё равно всегда равны 0, ибо адрес команды всегда кратен 4
 
- Короткие — условные 
 
- Пример программы для Mars - будем использовать пока что магические системные вызовы ввода и вывода десятичных чисел, находящихся в регистре
- Ввести два числа, вывести результат: - 1 li $v0 5 # Системный вызов №5 — ввести десятичное число 2 syscall # Результат — в регистр $v0 (он же $2) 3 move $t0 $v0 # Сохраняем результат в $t0 (он же $8) 4 li $v0 5 # $v0 нам нужен для ввода ещё одного числа 5 syscall 6 add $a0 $v0 $t0 # Складываем ввод с сохранённым, записываем в $a0 (он же $4) 7 li $v0 1 # Системный вызов №1 — вывести число из регистра $a0 8 syscall 9 li $v0 10 # Системный вызов №10 — останов программы 10 syscall 
 
 
Д/З
- Зарегистрироваться в EJudge, если кто не 
- EJudge: DoubleSum 'Двойная сумма' Input:- Ввести в столбик четыре целых числа. Первое сложить со вторым, третье — с четвёртым. Вывести две полученные суммы в строчку, без пробелов. - 12 23 -23 7 Output:- 12 23 -23 7 - 35-16 
