]]> ]]>

MIPS

Реализация языка программирования Assembler

MIPS ( 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 — используется для отладки.

Примеры:

Факториал:

Пример для версий MIPS32

13! и дальше вызывают переполнение, поэтому вывод такой:

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

]]>

Работа программистам