Материал: Архитектура и программирование MIPS-процессоров. Разинкин К.А

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Сумма задаётся в переменной amount (прим. переводчика: следует отметить, что разные высокоуровневые конструкции могут быть реализованы одинаково на ассемблере MIPS, и наоборот, одна и та же высокоуровневая конструкция может быть реализована на ассемблере по-разному.

Например, оператор switch можно реализовать на языке ассемблера, создав массив с адресами переходов, который индексируется аргументом switch).

Операторы switch/case

Код на языке высокого уровня switch (amount) {

case 20: fee = 2; break; case 50: fee = 3; break; case 100: fee = 5; break; default: fee = 0;

}

 

 

// equivalent function using if/else statements

if

(amount = = 20)

fee = 2;

else if (amount = = 50)

fee = 3;

else if (amount = = 100) fee = 5;

else

fee = 0;

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

# $s0 = amount, $s1 = fee

case20:

 

addi $t0, $0, 20

# $t0 = 20

bne $s0, $t0, case50 # amount = = 20? if not,

 

# skip to case50

addi $s1, $0, 2

# if so, fee = 2

j done

# and break out of case

case50:

 

addi $t0, $0, 50

# $t0 = 50

bne $s0, $t0, case100 # amount = = 50? if not,

# skip to case100

66

 

addi $s1, $0, 3

# if so, fee = 3

j

done

# and break out of case

case100:

 

 

 

addi $t0, $0, 100

# $t0 = 100

 

bne $s0, $t0, default # amount = = 100? if not,

 

 

 

# skip to default

addi $s1, $0, 5

 

# if so, fee = 5

j

done

 

# and break out of case

default:

 

 

add $s1, $0, $0

# fee = 0

done:

 

 

Циклы

Циклы многократно выполняют участок кода в зависимости от условия.

Циклы for и циклы while являются обычными конструкциями для организации циклов в языках высокого уровня. В этом разделе будет показано, как перевести их на язык ассемблера MIPS.

Циклы while

Циклы while многократно выполняют участок кода до тех пор, пока условие не станет ложным. В следующем примере кода цикл while ищет значение x такое, что 2x = 128. Цикл выполнится семь раз, прежде чем достигнет условия pow = 128.

Пример ЦИКЛ while

Код на языке высокого уровня int pow = 1;

int x = 0;

while (pow != 128)

{

pow = pow * 2; x = x + 1;

67

}

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

# $s0 = pow, $s1 = x

addi $s0, $0, 1

# pow = 1

addi $s1, $0, 0

# x = 0

addi $t0, $0, 128 # t0 = 128 for comparison while:

beq $s0, $t0, done # if pow = = 128, exit while loop

sll $s0, $s0, 1

# pow = pow * 2

addi $s1, $s1, 1

# x = x + 1

j while

 

done:

 

Вассемблерном коде в цикле while проверяется условие, противоположное условию, использованному на языке высокого уровня, аналогично тому, как это делается для оператора if/else. Если это противоположное условие истинно, то цикл while завершается.

Впредыдущем примере оператор цикла while сравнивает значение переменной pow со значением 128 и завершает цикл, если они равны.

Впротивном случае происходит удвоение pow (используя сдвиг влево), увеличение x на 1 и переход обратно на начало цикла while.

Циклы for

Циклы for, как и циклы while, многократно выполняют участок кода до тех пор, пока условие цикла не станет ложным. Однако циклы for добавляют поддержку счетчика цикла, который обычно хранит количество выполненных итераций цикла. Обычно цикл for выглядит следующим образом:

for (инициализация; условие; операция цикла) оператор

Код инициализации выполняется до того, как цикл for начнется. Условие проверяется в начале каждой итерации. Если условие не выполнено, цикл завершается. Операция цикла выполняется в конце каждой итерации.

68

Пример ниже складывает целые числа от 0 до 9. Счетчик итераций цикла, в данном случае i, инициализируется нулем и увеличивается на единицу в конце каждой итерации. Условие i != 10 проверяется в начале каждой итерации. Итерация цикла for выполняется только тогда, когда условие истинно, т.е. когда значение i не равно 10, иначе цикл завершается. В нашем случае цикл for выполняется 10 раз. Циклы for могут быть реализованы и при помощи циклов while, но цикл for часто удобнее.

Пример Цикл for

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

for (i = 0; i != 10; i = i + 1) { sum = sum + i ;

}

// equivalent to the following while loop int sum = 0;

int i = 0;

while (i != 10) { sum = sum + i; i = i + 1;

}

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

# $s0 = i, $s1 = sum

add $s1, $0, $0

# sum = 0

addi $s0, $0, 0

# i = 0

addi $t0, $0, 10

# $t0 = 10

for:

beq $s0, $t0, done # if i = = 10, branch to done add $s1, $s1, $s0 # sum = sum + i

addi $s0, $s0, 1 # increment i j for

done:

69

Сравнение по величине

До сих пор в рассмотренных примерах мы использовали инструкции beq и bne для сравнений и ветвлений на основе равенства или неравенства значений. Архитектура MIPS содержит инструкцию установить, если меньше (slt, от англ. set less than) для сравнения значений по величине. Инструкция slt устанавливает регистр rd в 1, если значение регистра rs меньше значения регистра rt. Иначе, в регистр rd записывается 0.

Циклы с использованием инструкции slt

Приведенный ниже код на языке высокого уровня складывает все степени двойки от 1 до 100. Транслируйте его на язык ассемблера.

// high-level code int sum = 0;

for (i = 1; i < 101; i = i * 2) sum = sum + i;

Решение: Код на языке ассемблера использует инструкцию установить, если меньше (slt) для выполнения сравнения в цикле for.

#MIPS assembly code

#$s0 = i, $s1 = sum

addi $s1, $0, 0

# sum = 0

 

addi $s0, $0, 1

# i = 1

 

addi $t0, $0, 101

# $t0 = 101

 

loop:

 

 

slt

$t1, $s0, $t0

# if (i < 101)

$t1 = 1, else $t1 = 0

beq $t1, $0, done

# if $t1 == 0 (i >= 101), branch to done

add $s1, $s1, $s0

# sum = sum + i

sll

$s0, $s0, 1

# i = i * 2

 

j

loop

 

 

done:

 

 

 

 

 

70

Источник: https://studfile.net/preview/16568788/