Различия между версиями 3 и 4
Версия 3 от 2019-02-23 21:19:57
Размер: 2764
Редактор: FrBrGeorge
Комментарий:
Версия 4 от 2019-02-23 22:08:26
Размер: 7026
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 16: Строка 16:
  * некоторые регистры более специальные, чем другие:
   * '''$0''' всегда равен 0, '''$31''' используется для подпрограмм и т. п.
Строка 19: Строка 21:
  * 3 базовых типа команд (с 26-битной частью адреса, с 16-битной и безадресные)   * 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 битов), используется для команд, у которых код операции равен (например, для op=0)
Строка 21: Строка 38:
   * Для некоторых операций (например, сложения) «знаковость» означает, что при переполнении будет возникать исключение, а «беззнаковость» — что не будет.
Строка 22: Строка 40:
   * сравнение только с 0 или = / ≠, сравнение на > / < двух регистров потребовало бы ''двух'' арифметических операций!
Строка 23: Строка 42:
  * Суть понятия псевдоинструкции:   * Суть понятия псевдоинструкции на примере `li регистр, число`:
Строка 25: Строка 44:
   * ...    * Нет никакой ''инструкции'' «положить I-число в регистр», зато есть инструкция «сложить I-число с `$0` (с нестрираемым нулём) и положить результат в регистр»
   * Если число в `li` больше 16 битов, псевдоинструкция раскладывается в две:
    1. записать старшую половину большого числа (это I-число) в старшую половину регистра (младшая при этом обнуляется),
    1. побитово добавить (OR) младшую половину большого числа в регистр
   * Обратите внимание на использование '''$1''' для хранения промежуточных данных
Строка 29: Строка 52:
  *   * Ввести два числа, вывести результат:
   {{{
        li $v0 5 # Системный вызов №5 — ввести десятичное число
        syscall # Результат — в регистр $v0 (он же $2)
        move $t0 $v0 # Сохраняем результат в $t0 (он же $8)
        li $v0 5 # $v0 нам нужен для ввода ещё одного числа
        syscall
        add $a0 $v0 $t0 # Складываем ввод с сохранённым, записываем в $a0 (он же $4)
        li $v0 1 # Системный вызов №1 — вывести число из регистра $a0
        syscall
        li $v0 10 # Системный вызов №10 — останов программы
        syscall
        }}}

Общая структура системы команд MIPS

базовая лекция Moodle

  • Принципы 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 битов), используется для команд, у которых код операции равен (например, для op=0)

    • знаковая и беззнаковая арифметика; регистры LO/HI для умножения/деления; побитовые операции
      • Для некоторых операций (например, сложения) «знаковость» означает, что при переполнении будет возникать исключение, а «беззнаковость» — что не будет.
    • условная пересылка и сравнение
      • сравнение только с 0 или = / ≠, сравнение на > / < двух регистров потребовало бы двух арифметических операций!

    • работа с памятью (в т. ч. псевдоинструкции типа li)

    • Суть понятия псевдоинструкции на примере li регистр, число:

      • li.png

      • Нет никакой инструкции «положить I-число в регистр», зато есть инструкция «сложить I-число с $0 (с нестрираемым нулём) и положить результат в регистр»

      • Если число в li больше 16 битов, псевдоинструкция раскладывается в две:

        1. записать старшую половину большого числа (это I-число) в старшую половину регистра (младшая при этом обнуляется),
        2. побитово добавить (OR) младшую половину большого числа в регистр
      • Обратите внимание на использование $1 для хранения промежуточных данных

    • переходы
  • Пример программы для Mars
    • будем использовать пока что магические системные вызовы ввода и вывода десятичных чисел, находящихся в регистре
    • Ввести два числа, вывести результат:
      •         li      $v0 5       # Системный вызов №5 — ввести десятичное число
                syscall             # Результат — в регистр $v0 (он же $2)
                move    $t0 $v0     # Сохраняем результат в $t0 (он же $8)
                li      $v0 5       # $v0 нам нужен для ввода ещё одного числа
                syscall
                add     $a0 $v0 $t0 # Складываем ввод с сохранённым, записываем в $a0 (он же $4)
                li      $v0 1       # Системный вызов №1 — вывести число из регистра $a0
                syscall
                li      $v0 10      # Системный вызов №10 — останов программы
                syscall

Д/З

TODO

  • Зарегистрироваться в EJudge
  • Решить простейшую задачу

LecturesCMC/ArchitectureAssembler2019/02_Mips_Architecture (последним исправлял пользователь FrBrGeorge 2019-11-13 10:12:31)