Давайте с самого начала (пропустив 2 системных вызова перед циклом):
Анализируемая строка hello worlds
расположена по адресу Str
t0
будет содержать числосимволов в hello worlds
.Это то, что нам нужно найти и напечатать.Инициализируется нулем:
li $t0, 0
t1
содержит адрес обрабатываемого в данный момент символа.Он инициализируется Str
, который является адресом hello worlds
, и в то же время является адресом его первого символа h
:
la $t1, Str
Цикл начинается:
iteration1:
Текущий обработанный символ загружен в t2
:
lb $t2, 0($t1)
Напомним, что lb reg, offset(addr)
подразумевает загрузку 1-байтового значения по адресу addr + offset
в регистр reg
.В нашем случае это подразумевает загрузку 1-байтового значения по адресу t1 + 0
в t2
.t1 + 0
- адрес текущего символа, т.е. h
.Следовательно, h
загружается в t2
beqz $t2, Tim
подразумевает переход к метке Tim
в случае, если t2
равен нулю.но t2
имеет значение h
, поэтому оно не равно нулю.Цель этой проверки - обнаружить нулевой терминатор, который обозначает конец строки.Как только мы обнаружим этот нулевой терминатор, мы все закончили, и цикл должен завершиться
addi $t0, $t0, 1
- мы увеличиваем наш счетчик (количество символов, которые мы обработали до сих пор).t0
становится 1
addi $t1, $t1, 1
- мы увеличиваем адрес обрабатываемого в данный момент символа.Другими словами, мы переходим к следующему символу строки (мы увеличиваем его на 1, потому что размер символа составляет 1 байт).Теперь t1
имеет адрес второго символа, который e
j Loop1
- мы начинаем новую итерацию
итерацию 2:
lb $t2, 0($t1)
-e
загружено в t2
beqz $t2, Tim
- e
не равно нулю, поэтому мы не переходим к Tim
и продолжаем цикл
addi $t0, $t0, 1
- t0
становится 2
addi $t1, $t1, 1
- t1
содержит адрес третьего символа, который l
j Loop1
- начать новую итерацию
и так далее, пока beqz $t2, Tim
не проверит, что t2
содержит ноль,в этом случае программа останавливает цикл и переходит к Tim