ний символов этих строк (вам потребуется транслитерировать ваше имя, используя латинский алфавит):
a)SOS
b)Cool!
c)(ваше собственное имя)
3.2.7.Повторите упражнение 6.6 для следующих строк: a) howdy
b) ions
c) To the rescue!
3.2.8.Покажите, как строки из упражнения 6.6 хранятся
вадресуемой побайтово памяти, начиная с адреса 0x1000100C:
(a) на машине с прямым порядком следования байтов и (b) на машине с обратным порядком следования байтов. Отметьте байтовые адреса всех байтов данных в обоих случаях.
3.2.9.Повторите упражнение 6.8 для строк из упражне-
ния 3.2.7.
3.2.10.Преобразуйте следующий код из языка ассемблера MIPS в машинный язык. Запишите инструкции в шестнадца-
теричном формате.
add $t0, $s0, $s1 lw $t0, 0x20($t7) addi $s0, $0, −10
3.2.11. Повторите упражнение 3.2.10 для следующего
кода:
addi |
$s0, $0, 73 |
sw |
$t1, −7($t2) |
sub |
$t1, $s7, $s2 |
3.2.12. |
Рассмотрим инструкции типа I. |
a)Какие инструкции из упражнения 6.10 являются инструкциями типа I?
b)Для каждой инструкции типа I из упражнения 6.10 примените расширение знака к непосредственному 16-битному операнду так, чтобы получилось 32-битное число.
111
3.2.13.Повторите упражнение 3.2.12 для инструкций из упражнения 3.2.11.
3.2.14.Преобразуйте следующую программу из машинного языка в программу на языке ассемблера MIPS. Цифрами слева показаны адреса инструкций в памяти. Цифры справа – это инструкции по соответствующим адресам. Объясните, что делает эта программа, предполагая, что перед началом её выполнения $a0 содержит некое положительное число n, а после завершения программы в $v0 получается некоторый результат. Также напишите эту программу на языке высокого уровня (например, С).
0x00400000 0x20080000
0x00400004 0x20090001
0x00400008 0x0089502A 0x0040000C 0x15400003 0x00400010 0x01094020 0x00400014 0x21290002 0x00400018 0x08100002 0x0040001C 0x01001020 0x00400020 0x03E00008
3.2.15 Повторите упражнение 3.2.15 для приведенного ниже машинного кода. Используйте значения $a0 и $a1 как входные данные. В начале программы $a0 содержит некоторое 32-битное число, а $a1 – адрес некоторого массива из 32 символов (типа char).
0x00400000 0x2008001F
0x00400004 0x01044806
0x00400008 0x31290001 0x0040000C 0x0009482A 0x00400010 0xA0A90000 0x00400014 0x20A50001 0x00400018 0x2108FFFF 0x0040001C 0x0501FFF9 0x00400020 0x03E00008
112
3.2.16.В архитектуре MIPS имеется инструкция nor, но отсутствует её вариант с непосредственным операндом nori. Тем не менее, команда nori может быть реализована существующими инструкциями. Напишите на языке ассемблера код со следующей функциональностью: $t0 = $t1 NOR 0xF234. Используйте наименьшее возможное число инструкций.
3.2.17.Реализуйте следующие фрагменты кода высокого уровня на языке ассемблера MIPS, используя инструкцию slt. Значения целочисленных переменных g и h хранятся в регистрах $s0 и $s1 соответственно.
(a)if (g > h)
g = g + h; else
g = g − h;
(b) if (g >= h) g = g + 1;
else
h = h − 1;
(c) if (g <= h) g = 0;
else
h = 0;
3.2.18. Напишите функцию на языке высокого уровня (например, С), имеющую следующий прототип: int find42(int array[], int size). Здесь array задаёт базовый адрес некоторого массива целых чисел, а size содержит число элементов в этом массиве. Функция должна возвращать порядковый номер первого элемента массива, содержащего значение 42. Если в массиве нет числа 42, то функция должна вернуть –1.
113
3.2.19.Функция strcpy копирует строку символов, расположенную в памяти по адресу src, в новое место с адресом dst.
// C code
void strcpy(char dst[], char src[]) { int i = 0;
do {
dst[i] = src[i];
} while (src[i++]);
}
a) Реализуйте приведенную выше функцию strcpy на языке ассемблера MIPS. Используйте $s0 для i.
b) Изобразите стек до вызова, во время и после вызова функции strcpy. Считайте, что перед вызовом strcpy $sp =
0x7FFFFF00.
3.2.20.Реализуйте функцию из упражнения 3.2.18 на языке ассемблера MIPS.
3.2.21Рассмотрим приведенный ниже код на языке ассемблера MIPS.
Функции func1, func2 и func3 – нелистовые (нетерминальные) функции, а func4 – листовая (терминальная). Полный код функций не показан, но в комментариях указаны регистры, используемые каждой из них.
0x00401000func1:... # func1 uses $s0–$s1
0x00401020 |
jal func2 |
… |
|
0x00401100 |
func2:...# func2 uses $s2–$s7 |
0x0040117C |
jal func3 |
… |
|
0x00401400 |
func3:...# func3 uses $s1–$s3 |
0x00401704 |
jal func4 |
… |
|
0x00403008 func4:...# func4 uses no preserved
0x00403118 jr $ra # registers a) Сколько слов занимает кадр стека у каждой из этих
функций?
114
b) Изобразите стек после вызова func4. Укажите, какие регистры хранятся в стеке и где именно. Отметьте каждый из кадров стека. Там, где это возможно, подпишите значения, сохранённые в стеке.
3.2.22. Каждое число в последовательности Фибоначчи является суммой двух предыдущих чисел. В табл. 3.2 перечислены первые числа последовательности fib(n).
Таблица 3.2
a)Чему равны значения fib(n) для n = 0 и n = –1?
b)Напишите функцию с именем fib на языке высокого уровня (например, С). Функция должна возвращать число Фибоначчи для любого неотрицательного значения n. Подсказка: используйте цикл. Прокомментируйте ваш код.
c)Преобразуйте функцию, написанную в части (b), в код на ассемблере MIPS.
После каждой строки кода добавьте строку комментария, поясняющего, что она делает.
3.2.23. Переведите приведенные ниже инструкции beq, j
иjal в машинный код. Адреса инструкций указаны слева от каждой из них:
(a)
0x00401000 beq $t0, $s1, Loop
0x00401004 ...
0x00401008 ...
0x0040100C Loop: ...
(b) |
|
0x00401000 |
beq $t7, $s4, done |
... |
... |
0x00402040 |
done: ... |
(c) |
|
0x0040310C |
back: ... |
... |
... |
|
115 |