- Изучаем MIPS-ассемблер
- Структура программы на MIPS-ассемблере
- Типы в MIPS-ассемблере
- Метки (символы)
- Основные директивы
- Формат данных в .data
- Регистры
- Инструкции MIPS
- Типы инструкций
- Инструкция syscall
- Арифметические инструкции
- Продолжение следует
- Google будет поддерживать архитектуру MIPS в Android наряду с ARM
Изучаем MIPS-ассемблер
Как говорит Википедия, MIPS – микропроцессор, разработанный компанией MIPS Computer Systems (в настоящее время MIPS Technologies) и впервые реализованный 1985 году. Существует большое количество модификаций этой архитектуры, созданных специально для 3D-моделирования, быстрой обработки чисел с плавающей запятой, многопотоковых вычислений. Различные варианты этих процессоров использутся в роутерах Cisco и Mikrotik, смартфонах, планшетах и игровых консолях.
Инструкции MIPS достаточно просты для понимания, и именно с него рекомендуется начинать изучение ассемблера. Чем сейчас, собственно, и займёмся.
Структура программы на MIPS-ассемблере
Вот так выглядит классическая программа на MIPS-ассемблере.
Всё, что начинается на точку – это директивы. Директива .data означает начало сегмента данных, .text – начало сегмента кода.
Всё, после чего следует двоеточие, – это метки ( v: , main: , loop: и endloop: ).
Весь текст, следующий после знака # – это комментарии.
А то, что остаётся – это, собственно, инструкции и псевдоинструкции (макросы).
Типы в MIPS-ассемблере
Вот сравнительная таблица основных типов в C++ и в MIPS:
Как можно увидеть в таблице, выбор типа в для переменной в MIPS основывается только на объёме памяти, который будет занимать эта переменная. Обратите внимание, что MIPS в этом плане не различает signed- и unsigned-переменные.
Метки (символы)
В коде выше мы использовали несколько меток.
Метки (их ещё называют символами или этикетками) используются для того, чтоб давать «имена» адресам в памяти. Эти символы разделены на 2 больших класса: этикетки данных (адреса глобальных переменных, которые находятся в секции .data , в этом случае v: ) и метки инструкций (адреса инструкций в секции .text , например main: , loop: ).
Данные в секции .data обычно сохраняются в памяти начиная с адреса 0x10010000. Инструкции же хранятся начиная с адреса 0x00400000. Так как каждая инструкция MIPS-ассемблера занимает ровно 32 бита, следующая таблица «метка-адрес» будет верна для нашей программы:
С помощью меток очень удобно работать с глобальными переменными и другими данными из .data , но об этом чуть позже.
Основные директивы
Мы уже рассмотрели несколько директив, а именно .data и .text , и уже известно, что первая предназначена для хранения данных и объявления глобальных переменных, а вторая – собственно для кода программы. Посмотрим на остальные директивы MIPS:
- объявляет символ sym глобальным и позволяет обращатся к нему из других файлов;
- объявляет, что данные, которые хранятся в sym имеют размер size, и делает sym глобальной меткой (см. предыдущую директиву);
- сохраняет строку str в памяти, не добавляя нулевой символ (\0) в конец;
- сохраняет строку str и добавляет в конец нулевой символ (\0);
- последовательно сохраняет в памяти байты b1, b2, . bn;
- последовательно сохраняет в памяти 16-битные значения h1, h2, . hn;
- последовательно сохраняет в памяти 32-битные значения w1, w2, . wn;
- последовательно сохраняет в памяти 64-битные значения dw1, dw2, . dwn;
- сохраняет в памяти числа с плавающей запятой f1, f2, . fn;
- сохраняет в памяти числа с плавающей запятой (двойная точность) d1, d2, . dn;
- выделить n байт в данном сегменте данных;
- выровнять все следующие данные до 2^n байт.
По поводу последней директивы: допустим, что в .data мы написали .align 1 . В таком случае даже если мы запишем в память, например в адрес 0x10010000 какое-то значение размером в 1 байт, следующий байт будет оставлен пустым, и если мы захотим записать ещё один байт в память, он уже получит адрес 0x10010002. В MIPS по умолчанию включено автоматическое выравнивание данных, и поэтому можно записать 16-битное значение ( .half ) только в чётный адрес памяти (0x10010000, 0x10010002, но не 0x10010003), 32-битное значение – только в адрес, кратный 4, а 64-битное – только в адрес, кратный 8.
Формат данных в .data
Данные в .data записываются в достаточно свободной манере. Нужно просто указать метку, тип данных и значение. В этом коде несколько примеров корректной записи данных:
Немного глубже мы рассмотрим типы данных по мере их использования в коде.
Регистры
Одна основных частей MIPS-процессора – это регистры. В стандартном MIPS-процессоре имеется 32 основных регистра и ещё 32 в первом сопроцессоре – модуле, который используется для вычислений с плавающей запятой. Каждый регистр имеет размер 32 бита, соответственно в него целиком помещается одно значение типа int . Для хранения переменной типа long необходимо использовать сразу два регистра. К каждому регистру можно обратиться по его порядковому названию и по его общему названию. Общее – немного более human-readable. Имеются следующие регистры:
- $zero ($0) – регистр, всегда содержащий значение 0 и доступный только для чтения;
- $at ($1) – временный регистр процессора;
- $v0-$v1 ($2-$3) – для результатов, возвращаемых функциями;
- $a0-$a3 ($4-$7) – для аргументов функций;
- $t0-$t9 ($8-$15, $24-$25) – для временных данных, можно использовать как угодно;
- $s0-$s8 ($16-$23, $30) – для постоянных данных, можно использовать как угодно;
- $k0-$k1 ($26-$27) – зарезервировано для ядра операционной системы;
- $gp ($28) – поинтер для глобальных переменных, практически не используется;
- $sp ($29) – поинтер стека, его значение всегда равно верхнему адресу стека;
- $ra ($31) – бог солнца адрес инструкции, из которой была вызвана функция;
- $f0 – для результатов, возвращаемых функцями, с плавающей запятой;
- $f4, $f6, $f8, $f10, $f16, $f18 – для временных данных с плавающей запятой;
- $f12, $f14 – для параметров функций с плавающей запятой
Инструкции MIPS
Примечание. C этого момента мы будем рассматривать MIPS-процессор, его инструкции и дополнения на примере замечательного симулятора MIPS под названием MARS, который можно загрузить отсюда. Имплементация MIPS в этом симуляторе полностью соответствует стандартам.
В коде в начале статьи мы уже выделили все функциональные части программы и определили инструкции и псевдоинструкции как то, что не является комментарием, символом (меткой) или директивой. Псевдоинструкции также называют макросами, они трансформируются в одну или несколько инструкций во время выполнения кода. Вот пример макроса:
переходит в набор инструкций:
Как видно, MIPS-программы всегда записываются по одной инструкции на строчку.
Типы инструкций
Существует три основных типа инструкций MIPS-ассемблера:
- тип R (register). В роли операндов используются три регистра – регистр назначения (сокр. $rd), первый аргумент ($rs), и второй аргумент ($rt). Пример такой инструкции – сложение трёх регистров: В данном случае в $t2 будет помещён результат сложения значений в $t0 и $t1.
- тип I (immediate). Операнды – два регистра и число. Пример инструкции типа I: После выполнения в регистр $t3 будет помещён результат сложения $t2 и числа 12.
- Тип J (jump). Единственный операнд – 26-битный адрес, куда нужно перейти. Инструкция перейдёт на адрес 128 в .text .
Также существуют инструкции для сопроцессоров, но их мы рассмотрим позже.
Инструкция syscall
syscall – одна из самых простых, но в то же время одна из самых значимых инструкций MIPS-ассемблера. Это – служебная инструкция, поэтому она рассматривается отдельно от остальных. syscall используется для обращения к операционной системе для произведения действий, которые процессор сам не в состоянии выполнить. Перед вызовом этой инструкции нужно положить в регистр $v0 служебный код – натуральное число от 1 до 12. В зависимости от кода операционная система будет производить одно или другое действие. Вот список служебных кодов и соответствующие им действия операционной системы, которые поддрерживает MARS:
Весь ввод и вывод происходит через консоль MARS’a.
Арифметические инструкции
Итак, рассмотрим некоторые основные арифметические инструкции. Будут использованы некоторые сокращения: rd – регистр, куда пишется результат, rs – первый аргумент, rt – второй аргумент. Также может встретиться imm16 – 16-битное целое число или imm5 – 5-битное натуральное число.
- сумма rs и rt записывается в регистр rd. Аккуратно, может вызвать переполнение.
- rd = rs — rt. Также можно получить переполнение.
- почти то же самое, что и предыдущая инструкция, но эта не может вызвать переполнение. Для арифметических вычислений предпочтительно использовать именно эту инструкцию.
- rd = rs — rt. Также без переполнения, и поэтому рекомендуется к использованию.
- rt = rs + 16-битное целое число. Как и add , может вызывать переполнение.
- то же самое, но без возможности переполнения. Use it.
Кстати, imm16 по умолчанию интерпретируются как позитивные. Например:
Если нужно добавить отрицательное значение, то нужно явно это указать:
Давайте посмотрим на реальные вычисления с помощью этих инструкций. Возьмём, к примеру, следующий код (на C++):
int f = (g+h) — (i-j);
И переведём этот код в MIPS-инструкции. Сначала нужно вычислить значение справа от знака ‘=’, а потом присвоить его переменной f. Допустим, что переменная f у нас будет находиться в регистре $s0, g – в $s1, h – в $s2, i – в $s3, а j – в $s4. Вот что получается:
А теперь можно протестировать получившийся код в MARS. Загрузите черновик вот отсюда и откройте его в MARS:
Допишите код вместо комментария. Теперь можно его выполнить. Сначала выберите Run -> Assemble:
Теперь снимите галочку с пункта Hexadecimal Values, чтобы увидеть десятичные значения в регистрах, и выберите Run -> Go:
Значение в $s0 после выполнения программы должно быть равно 12.
Продолжение следует
В следующей статье рассмотрим логические инструкции, а также умножение и деление целых чисел. В ней же попробуем работать с памятью и стеком. А пока предлагаю вам попробовать переписать вот этот код на MIPS-ассемблер:
Источник
Google будет поддерживать архитектуру MIPS в Android наряду с ARM
Компания Google может ввести в Android поддержку процессоров MIPS Technologies, что поможет последней закрепиться на рынке смартфонов, планшетов и других устройств на базе этой мобильной ОС без необходимости портирования кода после выхода новых сборок. Ожидается, что в ближайшие недели начнётся разработка GNU-компилятора для чипов с архитектурой MIPS, который будет включён в набор разработчиков Android. Причём Google встроит полную поддержку двоичного интерфейса прикладных программ (ABI) во всём коде Android и его библиотеках к запуску в третьем квартале следующей версии под кодовым именем Jelly Bean.
Главный мобильный конструктор MIPS Эмит Рохатджи (Amit Rohatgi) сообщил на конференции Linley Tech Mobile, что Google начала обращать внимание на объёмы поставок Android-планшетов на базе MIPS. Он также сообщил, что таких планшетов уже отгружено около 1,8 млн, все они представлены преимущественно дешёвыми системами от китайских OEM-производителей и построены на SoC, произведённых такими компаниями, как Ingenic Semiconductor, по лицензиям MIPS. Крупнейшим мировым поставщиком Android-планшетов на базе платформ от Ingenic с недавних пор стала Philips. Как и китайские бренды, она использует 7-дюймовый формат.
Недавние новости сообщают, что MIPS Technologies может готовить сделку по продаже всех своих активов в связи с ухудшающимися финансовыми результатами деятельности. Архитектура уже широко используется в сетевом оборудовании и телевизионных приставках, а теперь начинает получать распространение и на мобильном рынке, где владычествует ARM.
MIPS тесно сотрудничала с Google над реализацией программной поддержки своей архитектуры в Android, что, по слухам, должно совершится вскоре. Впрочем, пока поисковой гигант официально не подтвердил свои планы на этот счёт. Если сообщения главного конструктора MIPS подтвердятся, не может ли это свидетельствовать в пользу того, что Google может проявлять интерес к MIPS не только как архитектуре, получающей распространение на мобильном рынке и способной дать Android дополнительное преимущество, но также как потенциальный покупатель MIPS Technologies, на что указывают последние слухи.
«[Сейчас] моя самая большая головная боль и работа — быть уверенным, что все наборы инструментов завершены для Android на MIPS», — отметил Эмит Рохатджи, добавив: «Нам совершенно необходимо принести официальную поддержку MIPS ABI на Android, и это произойдёт».
В отношении программной поддержки, 85% всех приложений для Android исполняются через встроенный интерпретатор виртуальной машины Dalvik, но остальная часть представленных в Google Play программ числом 80 тысяч написана именно под архитектуру ARM и исполняется напрямую. Таким образом, подавляющая часть Android-программ будет работать на устройствах с архитектурой MIPS. Необходимый для этого код уже существует, но официальная поддержка Google и интеграция кода в стандартную сборку ОС позволила бы упростить часто рутинную работу по оптимизации всех необходимых приложений под MIPS.
Эмит Рохатджи работает с ведущими разработчиками приложений для обеспечения поддержки MIPS в их коде. Эмулятор MagiCode уже доступен для скачивания, так что пользователи могут запускать ARM-базированные Android-приложения на MIPS-системах.
Хорошей новостью для китайских производителей мобильных чипов является то, что лицензионные отчисления за использование архитектуры MIPS на порядок меньше $5 млн, которые компании должны платить ARM за использование патентованного дизайна Cortex-A9. Система на чипе Ingenic работает на частоте 1,2 ГГц и по мощности сопоставима с Cortex-A8. Первые образцы чипов с двумя MIPS-ядрами будут выпущены в этом году, этот процессор нацелен на уровень производительности Cortex-A9, но будет отличаться немного более низким энергопотреблением. 64-битный процессор Ingenic, находящийся на начальной стадии разработки дизайна, нацелен на противостояние с Cortex-A15 и запланирован к выходу в конце 2013 года, сообщает Эмит Рохатджи.
Планшет Paladin Novo 7 от китайской компании Ainol на базе MIPS-платформы Ingenic и Android 4.0
Intel также добилась от Google, чтобы её архитектура x86 получила поддержку в Android наряду с ARM. Энди Рубин (Andy Rubin), возглавляющий работу над Android в Google, объявил на прошлогодней конференции разработчиков Intel о более тесном сотрудничестве между двумя компаниями.
Источник