MIPS
Реализация языка программирования AssemblerMIPS ( Microprocessor without Interlocked Pipeline Stages ) создан компанией MIPS Technologies.
Директивы
- .data — хранение данных и объявление глобальных переменных.
- .text — сам код программы.
- .globl s — объявляет метку s глобальной.
- .extern s size — объявляет, что s имеет размер size и делает s глобальным.
- .align n — выравнивание всех следующих данных на 2^n байт.
- .ascii str — объявляет строку str без нулевого символа.
- .asciiz str — объявляет строку str с нулевым символом.
- .byte / .half / .word / .dword — объявление основных типов данных.
- .float / .double — объявление данных с плавающей точкой.
- .space n — выделить n байт.
Данные и пример .data
Существует 4 основных типа данных в MIPS ассемблере, byte (8 бит), halfword (16 бит), word (32 бита) и double word (64 бита).
Формат объявления: name: type value(s)
Пример:
.data
array1: .byte 'a','b','c'
num1: .word 2,3,4,5,6
array2: .space 9000
string: .asciiz "I like MIPS"
var1: .float -5.3
var2: .double 0.3e-10
Регистры
К регистру можно обратиться по его имени и по его номеру. Номер указан в скобках. Оригинальный MIPS процессор содержит 32 своих регистра и 32 регистра в первом сопроцессоре ($f0 — $f31)
- $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) — указатель на стек, его значение равно верхнему адресу стека.
- $fp ($30) — указатель на фрейм.
- $ra ($31) — содержит адрес инструкции, из которого была вызвана функция.
- $f0 – для результатов, возвращаемых функцями, с плавающей запятой.
- $f4, $f6, $f8, $f10, $f16, $f18 – для временных данных с плавающей запятой.
- $f12, $f14 – для параметров функций с плавающей запятой.
- hi,lo — используется при умножении и делении.
- pc — программный счетчик.
Типы инструкций
- R (register) — Операнды — 3 регистра, регистр назначения, первый аргумент и второй аргумент.
- I (immediate) — Операнды — 2 регистра и число.
- J (jump) — Операнд — 26 битный адрес , куда надо “прыгнуть”.
Инструкции MIPS
Здесь описаны основные инструкции MIPS ассемблера.
Арифметические
- add $x, $a, $b — x = a+b , может вызвать переполнение.
- addu $x, $a, $b — как и выше, но не вызывает переполнения.
- addi $x, $a, i16 — как и add , но i16 — 16-битное целое число, может вызвать переполнение.
- addiu $x, $a, i16 — как и выше, но не вызывает переполнения.
- sub $x, $a, $b — x = a-b , может вызвать переполнение.
- subu $x, $a, $b — как и выше, но не вызывает переполнения.
- mult $a, $b — умножение a и b, результат записывается в регистры lo и hi.
- mfhi $x — присваивает регистру x значение регистра hi.
- mflo $x — присваивает регистру x значение регистра lo.
- div $a, $b — деление a на b, целое записывается в lo, а остаток в hi.
- divu $a, $b — как и выше, только не вызывает переполнения.
- move $x, $y — присваивает x значение y.
Управляющие структуры
Переходы
- j target — переход на метку target.
- jr $x — перейти по адресу, содержащему в регистре x.
- jal target — копирует содержимое программного счетчика в регистр $ra и переходит по метке target.
Условные переходы
- b target — безусловный переход на метку target.
- beq $a, $b, target — перейти на метку target, если a = b.
- blt $a, $b, target — перейти на метку target, если a < b.
- ble $a, $b, target — перейти на метку target, если a <= b.
- bgt $a, $b, target — перейти на метку target, если a > b.
- bge $a, $b, target — перейти на метку target, если a >= b.
- bne $a, $b, target — перейти на метку target, если a <> b.
Прямая и косвенная адресация
- la — $x, var — копировать RAM адрес var (объявлено в .data) в регистр x.
- lw $x, s($y) — загрузить слово, содержащее в RAM памяти по адресу $x, в регистр $y. Можно дописать смещение от адреса в регистре (s).
- li — $x, i16 — загрузить 16 или 32-битное число в регистр $x.
- sw — $x, s($y) — зарезервировать машинное слово, содержащее в регистре $x, в RAM памяти по адресу $y. Можно дописать смещение (s).
Другие инструкции
syscall
Довольно важная инструкция в MIPS ассемблере, которая использует системные вызовы операционной системы. Прежде чем использовать ее, нужно загрузить в регистр $v0 один из служебных кодов от 1 до 16 . Список кодов и соответствующих действий операционной системы:
- 1 — вывести на экран натуральное число, которое находится в регистре $a0.
- 2 — вывести на экран число с плавающей точкой, которое находится в регистре $f12.
- 3 — вывести на экран число с плавающей точкой (двойная точность), которое находится в регистре $f12.
- 4 — вывести строку , которая находится в регистре $a0 (с нулевым символом).
- 5 — считать натуральное число и занести его в регистр $v0.
- 6 — считать число с плавающей точкой и занести его в регистр $f0.
- 7 — считать число с плавающей точкой (двойная точность) и занести его в регистр $f0.
- 8 — считать строку, $a0 — адрес строкового буфера , $a1 — сколько символов нужно считать.
- 9 — ?
- 10 — выйти из программы.
- 11 — вывести символ в $a0.
- 12 — считать символ и занести его в $a0.
- 13 — открыть файл, $a0 — адрес нуль-строки, содержащей имя файла, $a1 — флаг, $a2 — режим. После операции $v0 будет содержать дескриптор файла.
- 14 — читать из файла, $a0 — дескриптор, $a1 — адрес входного буфера, $a2 — сколько символов прочитать. После операции $v0 будет содержать количество прочитанных символов.
- 15 — писать в файл, $a0 — дескриптор, $a1 — адрес выходного буфера, $a3 — сколько символов записать. После операции $v0 будет содержать количество записанных символов.
- 16 — закрыть файл , дескриптор находится в $a0.
nop — машинный код 00000000 , ничего не делает.
break — используется для отладки.
Ссылки:
Примеры:
Факториал:
Пример для версий MIPS3213! и дальше вызывают переполнение, поэтому вывод такой:
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 1932053504
14! = 1278945280
15! = 2004310016
.data
string1: .asciiz "! = "
string2: .asciiz "\n"
.text
main:
li $t1, 1
li $t2, 1
j loop
loop:
li $v0, 1
la $a0, ($t2)
syscall
la $a0, string1
li $v0, 4
syscall
mult $t1,$t2
mflo $t1
li $v0, 1
la $a0, ($t1)
syscall
la $a0, string2
li $v0, 4
syscall
addiu $t2,$t2,1
beq $t2, 16, endloop
j loop
endloop:
li $v0, 10
syscall
Числа Фибоначчи:
Пример для версий MIPS32Эмулятор MARS. Вывод консоли MARS:
The Fibonacci numbers are:
1 1 2 3 5 8 13 21 34 55 89 144
-- program is finished running --
Программа выводит 15 чисел Фибоначчи. Количество чисел можно изменить в секции .data.
.data
space:.asciiz " "
head: .asciiz "The Fibonacci numbers are:\n"
fib: .word 0 : 15
size: .word 15
.text
main:
la $t0, fib
la $t5, size
lw $t5, 0($t5)
li $t2, 1
add.d $f0, $f2, $f4
sw $t2, 0($t0)
sw $t2, 4($t0)
addi $t1, $t5, -2
loop:
lw $t3, 0($t0)
lw $t4, 4($t0)
add $t2, $t3, $t4
sw $t2, 8($t0)
addi $t0, $t0, 4
addi $t1, $t1, -1
bgtz $t1, loop
la $a0, fib
move $a1, $t5
jal print
li $v0, 10
syscall
print:
add $t0, $zero, $a0
add $t1, $zero, $a1
la $a0, head
li $v0, 4
syscall
out:
lw $a0, 0($t0)
li $v0, 1
syscall
la $a0, space
li $v0, 4
syscall
addi $t0, $t0, 4
addi $t1, $t1, -1
bgtz $t1, out
jr $ra
Комментарии
]]>blog comments powered by Disqus
]]>