Reputation: 3
We recently wrote this code in class. I went through and adding comments that explain to myself how it works. I just don't get how the loop counts the number of chars/spaces in the string. Could someone translate it to me?
#Comment
.data
Str:.asciiz "hello worlds"
prompt:.asciiz "The given string is: "
ans:.asciiz "\n The number of chr and spaces is = "
.text
.globl main
main:
la $a0, prompt #load string prompt into register a0
li $v0, 4 #print string commmand(prints the prompt)
syscall #executes the command
la $a0, Str #loads Str into a0
li $v0, 4 #print string commnad
syscall #executes the command
li $t0, 0 #set t0 to 0
la $t1, Str #load Str into register t1
Loop1: #begins the loop SECTION I DONT UNDERSTAND
lb $t2, 0($t1) #loads byte into t2?
beqz $t2, Tim #if t2 == to zero go to Tim ?
addi$t0,$t0,1 #incremet t0 by 1 ?
addi$t1,$t1,1 #initialize t1 to 1 ?
j Loop1
syscall #executes the loop
Tim:
la$a0,ans #load ans into a0
li$v0,4 #print ans string
syscall #executes command
move$a0,$t0 #move t0 to a0
li$v0,1 #print int
syscall #execute command
Upvotes: 0
Views: 189
Reputation: 26646
This code is counting bytes in a null-terminated C-style string.
Let's translate this to C to see what it is doing, here we're using the if-goto style mimicking assembly's flow of control.
Loop1:
int ch = *ptr;
if ( ch == 0 ) goto Tim; // ch is $t2
counter++; // counter is $t0
ptr++; // ptr is $t1
goto Loop1;
And if we translate that to structured programming we get:
while ( *ptr != '\0' ) { ptr++; counter++; }
Make sense?
As an aside, the syscall
just after the loop does not have any of the normal syscall setup, so appears suspicious; however, to be clear, it is dead code — code located in between an unconditional jump and the next label is (almost) certainly unreachable by any flow of control of the program (we call that dead code; it should be removed — and the comment is erroneous).
Using $t0
— a calling convention volatile (scratch) register — to hold the counter live across a print-style syscall is also suspicious. Sometimes this will work but in other environments, not. It would be more proper to use a callee-saves (preserved/non-volatile) register like $s0
, or a memory location rather than relying on $t0 to be unchanged.
Upvotes: 0
Reputation: 3544
Let's go from the very beginning (skipping 2 syscalls before the loop):
The analyzed string is hello worlds
located at address Str
t0
will contain the number of characters in hello worlds
. This is what we need to find and print. It is initialized by zero:
li $t0, 0
t1
contains the address of the character currently processed. It is initialized by Str
which is the address of hello worlds
and at the same time it is the address of its first character h
:
la $t1, Str
The loop begins:
iteration1:
Currently processed character is loaded into t2
:
lb $t2, 0($t1)
Recall that lb reg, offset(addr)
implies loading 1-byte value at address addr + offset
into register reg
. In our case, it implies loading 1-byte value at address t1 + 0
into t2
. t1 + 0
is the address of current character i.e. h
. Hence h
is loaded into t2
beqz $t2, Tim
implies jumping to label Tim
in case if t2
is zero. but t2
has value h
so it is not zero. The purpose of this check is to detect the null-terminator which denotes the end of string. As soon as we detect that null-terminator, we are all done and the loop must finish
addi $t0, $t0, 1
- we increment our counter (the number of characters we have processed so far). t0
becomes 1
addi $t1, $t1, 1
- we increment the address of the character currently processed. In other words we move on to the next character of the string (we increment it by 1 because character size is 1 byte). Now t1
has the address of the second character which is e
j Loop1
- we start a new iteration
iteration 2:
lb $t2, 0($t1)
- e
is loaded into t2
beqz $t2, Tim
- e
is not zero so we don't jump to Tim
and continue the loop
addi $t0, $t0, 1
- t0
becomes 2
addi $t1, $t1, 1
- t1
contains the address of third character which is l
j Loop1
- start new iteration
and so on until beqz $t2, Tim
checks that t2
contains zero, in which case the program stops the loop and jumps to Tim
Upvotes: 1