Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

3222

.pdf
Скачиваний:
5
Добавлен:
15.11.2022
Размер:
3.54 Mб
Скачать

Длина команд в архитектуре MIPS составляет 32 бита, при этом некоторые из них используют только часть из этих бит. И хотя можно было бы сделать длину команд переменной, это излишне усложнило бы архитектуру.

Для простоты можно было бы также определить единый формат для всех инструкций, но, как уже говорилось, такой подход обернулся бы серьезными ограничениями. В архитектуре MIPS в качестве компромисса используются три формата инструкций: типа R, типа I типа J. Небольшое количество форматов обеспечивает определенное единообразие между всеми тремя типами и, как следствие, более простую аппаратную реализацию. При этом разные форматы позволяют учитывать различные потребности инструкций, как, например, необходимость хранить большие константы внутри инструкций.

Инструкции типа R используют три регистровых операнда. Инструкции типа I используют два регистровых операнда и 16-битнуюконстанту. Инструкции типа J (англ.: jump

– прыжок, переход) используют 26-битную константой.

Инструкции типа R

Название типа R является сокращением от регистрового типа (англ. register-type). Инструкции типа R используют три регистра в качестве операндов: два регистра-источника и один регистр-назначение. На рис. 2.1 показан машинный формат команды типа R. 32-битная команда состоит из шести полей: op, rs, rt, rd, shamt и funct. Каждое поле состоит из пяти или шести бит.

Рис.2.1. Формат команды типа R

51

Операция, выполняемая командой, закодирована двумя полями, отмеченными синим цветом: полем op (также называемым opcode иликодом операции) и полем funct (также называемым функцией). У всехкоманд типа R поле opcode равно нулю. Операция, выполняемая этими командами, определяется исключительно полем funct. Например, поля opcode и funct у

инструкции add равны 0 (0000002) и 32 (1000002) соответ-

ственно. Аналогично, у команды sub поля opcode и funct равны 0 и 34. Операнды закодированы тремя полями: rs, rt и rd. Поля содержат номера регистров, приведенные в п.1.1.1. Например, $s0 – это регистр с номером 16. Регистры rs и rt являются регистрами-источниками, а rd – регистром-назначением (или регистром результата).

Пятое поле, shamt, используется только для операций сдвига. В такихкомандах двоичное значение, хранимое в 5- битном поле shamt, задаёт величину сдвига (англ.: shiftamount). У всех остальных команд типа R поле shamt равно 0.

На Рис. 2.2 показан машинный код для двух инструкций типа R – add иsub. Обратите внимание на то, что в инструкции на языке ассемблера регистр-назначение идёт первым, а в команде на машинном языке он третий. Например, в ассемблерной инструкции add $s0, $s1, $s2 поле rs = $s1 (17), поле rt = $s2

(18), а поле rd = $s0 (16).

Рис. 2.2. Машинный код для инструкций типа R

В табл. B.1 и табл. B.2 приложения 1 перечислены значения поля opcode для всех команд, встречающихся в этой книге, и значения поля funct для команд типа R.

52

Пример. Трансляция с языка ассемблера в машинный

язык.

Транслируйте приведенную ниже ассемблерную инструкцию в машинный язык add $t0, $s4, $s5

Решение: как показано в п. 1.1.1, номера регистров $t0, $s4 и $s5 равны 8, 20 и 21 соответственно. Согласно табл. B.1 и табл. B.2, поле opcode для команды add равно нулю, а поле funct равно 32. Поля и получившийся машинный код показаны на рис. 2.3. простейший способ получить шестнадцатеричный машинный код – это сначала записать машинный код в двоичном виде, а затем поделить его на группы по четыре бита, которые заменить соответствующими шестнадцатеричными цифрами. Таким образом, для этой инструкции машинный код равен 0x02954020.

Рис. 2.3. Машинный код для инструкции типа R из примера

Инструкции типаI

Название типа I является сокращением от непосредственного типа (англ. immediate-type). Инструкции типа I используют в качестве операндов два регистра и один непосредственный операнд (константу).

На рис. 2.4 показан формат машинной команды типа I. 32-битная команда состоит из четырёх полей: op, rs, rt и imm. Первые три поля (op, rs и rt) аналогичны таким же полям в командах типа R. Поле imm (сокр. от англ. immediate) содержит 16-битную константу.

Рис.2.4. Формат команды типа I

53

Операция определяется исключительно полем opcode, отмеченным синим цветом. Операнды заданы в трёх полях: rs, rt и imm. Поля rs и imm всегда используются как операндыисточники. Поле rt в некоторых командах (например, addi и lw) содержит номер регистра-назначения, в других (например, sw)

– номер регистра-источника.

На рис. 2.5 приведено несколько примеров кодирования инструкций типа I. Вспомним, что отрицательные значения констант записывают в виде 16-битных чисел, представленных в дополнительном коде.

В инструкции на языке ассемблера поле rs указывают первым в том случае, когда оно содержит номер регистраназначения, но в команде машинного языка оно всегда является вторым по счету.

Инструкции типа I содержат 16-битную константу imm, но константы участвуют в 32-битных операциях. Например, инструкция lw добавляет 16-битное смещение к 32битному базовому адресу. Что же произойдёт в верхних 16 битах? 16-битные константы сначала будут расширены до 32 бит следующим образом: у неотрицательных констант верхние 16 бит будут заполнены нулями, а у отрицательных констант они будут заполнены единицами. Этот приём называется расширением знака. N-битное число расширяется знаком до M-битного числа (M > N) путём копирования знакового (старшего) бита N-битного числа во все старшие биты M-битного числа.

Расширение знака у числа, представленного в дополнительном коде, не меняет его значения. После расширения константы будет выполнена основная операция инструкции.

Рис. 2.5. Машинный код для инструкций типа I

54

Большинство команд MIPS производят расширение знака у непосредственных операндов. Например, addi, lw и sw производят расширение знака при использовании как положительных, так и отрицательных констант. Исключением из правила являются логические операции (andi, ori, xori), которые вместо расширения знака делают дополнение нулями, заполняя верхнюю половину теперь уже 32-битной константы нулями.

Пример.Трансляция инструкций типа I в машинный код. Транслируйте приведенную ниже инструкцию в машин-

ный код. $s3,−24($s4)

Решение: согласно п.1.1.1, номера регистров $s3 и $s4 равны 19 и 20 соответственно. Как показано в Табл. B.1, код операции (opcode) команды lw равен. Поле rs указывает на регистр $s4, содержащий базовый адрес, а поле rt указывает на регистр-назначение $s3. Поле imm, хранящее непосредственный операнд, содержит смещение, равное −24. Поля и получившийся машинный код показаны на рис. 2.6.

Рис. 2.6. Машинный код для инструкций типа I из примера

Инструкции типа J

Название типа J является сокращением от английского слова прыжок (англ.: jump). Этот формат используется только для инструкций безусловного перехода и ветвления. Как показано на рис. 2.7, в формате команд этого типа определён только один 26-битный операнд addr.

Рис. 2.7. Формат команды типа J

55

Как и другие команды, команды типа J начинаются с 6-битного поля кода операции (opcode). Оставшиеся биты используются для указания адреса перехода (addr).

2.2.Арифметические и логические инструкции

Вархитектуре MIPS определены разнообразные арифметические и логические инструкции. Сейчас мы кратко с ними ознакомимся поскольку они пригодятся нам в дальнейшем для построения высокоуровневых программных конструкций.

Вархитектуре MIPS имеются логические операции AND, OR, XOR и NOR. Соответствующие им одноименные инструкции типа R производят побитовые операции над значениями двух регистров-источников и помещают результат в ре- гистр-назначение. На Рис. 2.8 продемонстрированы примеры выполнения этих операций с двумя исходными значениями, 0xFFFF0000 и 0x46A1F0B7. На рисунке показаны значения, попадающие в регистр-назначение rd после того, как инструкции выполнены.

Рис. 2.8. Логические операции

Инструкция and полезна для наложения маски (англ. masking) на биты, т.е. для обнуления ненужных битов. На рис. 2.8 показана операция 0xFFFF0000 AND 0x46A1F0B7 = 0x46A10000. Инструкция and маскирует два младших байта и помещает два старших незамаскированных байта со значением

56

0x46A1 из регистра $s2 в регистр $s3. Маска может быть наложена на любое подмножество битов регистра.

Инструкцию or хорошо использовать для объединения битов из двух регистров. Например, в результате операции

0x347A0000 OR 0x000072FC = 0x347A72FC мы получили ком-

бинацию двух значений.

В архитектуре MIPS не определена операция инвертирования битов NOT, но так как A NOR $0 = NOT A, то инструкцию NOR можно использовать в качестве замены (прим. переводчика: инструкция NOR сначала делает операцию OR с исходными значениями, затем побитно инвертирует результат этой операции).

Логические инструкции также могут работать с непосредственными операндами. Это такие инструкции типа I, как andi, ori и xori. Инструкция nori не определена потому, что редко нужна и легко может быть заменена уже имеющимися инструкциями.

На рис. 2.9 продемонстрированы примеры выполнения инструкций andi, ori и xori.

На рисунке показаны значения регистра-источника и непосредственного операнда, а также содержимое регистраназначения rt по завершении выполнения инструкций. Поскольку эти инструкции работают с 32-битным значением регистра и 16-битной константой, то сначала они дополняют константу до 32 бит нулями.

Рис. 2.9. Логические операции над непосредственными операндами

57

Инструкции сдвига сдвигают значение в регистре влево или вправо на любое заданное количество бит, вплоть до 31. Операции сдвига фактически умножают или делят сдвигаемые значения на степени двойки. В архитектуре MIPS существуют следующие инструкции сдвига: sll (логический сдвиг влево, англ.: shift left logical), srl (логический сдвиг вправо, англ.: shift right logical) и sra (арифметический сдвиг вправо, англ.: shift right arithmetic).

На рис. 2.10 показан машинный код инструкций sll, srl и sra. В регистре rt (т.е. $s1) хранится 32-битное значение, которое нужно сдвигать, поле shamt задаёт величину сдвига (4). Результат сдвига помещается в регистр rd.

Рис. 2.10. Машинные коды инструкций сдвига типа R

Рис. 2.11 иллюстрирует пример работы инструкций сдвига sll, srl и sra. Сдвиг значения влево на N битов эквивалентен умножению на 2N. Аналогично, арифметический сдвиг значения вправо на N битов эквивалентен делению на 2N.

Рис. 2.11. Операции сдвига

58

Загрузка констант

Как показано в представленном ниже примере кода, инструкцию addi удобно использовать для присвоения переменным значений 16-битных констант.

16-Битная константа

Код на языке высокого уровня int a = 0x4f3c;

Код на языке ассемблера MIPS

# $s0 = a

addi $s0, $0, 0x4f3c # a = 0x4f3c

Для присвоения переменным значений 32-битных констант следует использовать инструкцию lui (англ.: load upper immediate), которая загружает константу в старшие 16 бит регистра и обнуляет младшие 16 битов, а также инструкцию ori для загрузки константы в младшие 16 бит без изменения старших, как показано в примере ниже.

32-Битная константа

Код на языке высокого уровня int a = 0x6d5e4f3c;

Код на языке ассемблера MIPS

# $s0 = a

lui $s0, 0x6d5e

# a = 0x6d5e0000

ori $s0, $s0, 0x4f3c

# a = 0x6d5e4f3c

Инструкции умножения и деления

Умножение и деление отличаются от других арифметических операций. Умножение двух 32-битных чисел даёт 64битное произведение. Деление двух 32-битных чисел даёт 32битное частное и 32-битный остаток.

В архитектуре MIPS определено два регистра специального назначения hi и lo, в которые сохраняются результаты

59

умножения и деления. Инструкция

mult $s0, $s1

умножает

значения из регистров

$s0 и $s1. Старшие 32 бита произведения

помещаются в регистр

hi, а младшие –

в регистр lo. Аналогично,

инструкция div $s0, $s1 вычисляет значение $s0/$s1.

Частное по-

мещается в lo, а остаток – в hi.

 

 

В архитектуре MIPS есть и другая команда умножения,

которая

помещает

32-битный результат в регистр общего

назначения.

 

 

 

 

Инструкция

mul $s1, $s2, $s3

умножает значения из

$s2 и $s3

и сохраняет 32-битный результат в $s1

(прим. пе-

реводчика: при использовании инструкции mul старшие 32 бита произведения нигде не сохраняются).

2.3. Переходы

Преимуществом компьютера над калькулятором является способность принимать решения. Компьютер выполняет разные задачи в зависимости от входных данных. Например,

операторы if/else, операторы switch/case, циклы while и for вы-

полняют те или иные части кода в зависимости от результата проверки некоторых условий.

Для последовательного выполнения инструкций счетчик команд увеличивается на 4 после каждой из них. Инструкции переходов изменяют счетчик программы для того, чтобы пропустить некоторые участки кода или повторить предыдущий код. Инструкции условных переходов, также называемые инструкциями ветвления (англ.: branch), проверяют какое-либо условие и осуществляют переход только в том случае, если проверка возвращает ИСТИНУ. Инструкции безусловного перехода (англ.: jump) осуществляют переход всегда.

Условные переходы

Система команд MIPS содержит две основные инструкции условного перехода: ветвление при равенстве (beq, от

60

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]