Reputation: 31
I want to convert a while loop like that:
i=0;
while ( (s[i]!='t') && (i<=20) ) {
d[i]=c[i];
i++;
}
with 2 conditions to assembly code. how can i do that? below is the version with 1 condition in the while.
#################################################
# lab3_3a.s #
# while loop char!=ASCII 0 #
#################################################
.text
.globl __start
__start: # execution starts here
li $t1,0 # counter for string
li $s0,'t' # chararacter to end copy
while: lbu $t0,string($t1) # load a character
sb $t0,copy($t1) # copy character
beq $t0,$s0,end # if character to end copy then exit loop
addi $t1,$t1,1 # increment counter
b while # repeat while loop
end: li $t2,0
sb $t2,copy($t1) # append end character to copied string
la $a0,copy # display copy
li $v0,4
syscall
li $v0,10 # exit
syscall
.data
string: .asciiz "Mary had a little lamb"
copy: .space 80
thanks guys.
Upvotes: 2
Views: 1612
Reputation: 16596
i=0;
while ( (s[i]!='t') && (i<=20) ) {
d[i]=c[i];
i++;
}
Would contain two bugs, if s
would be defined as char s[20];
, first the (i<=20)
would be one-too-much. It's very unusual to use <=
in array length tests, it may be still correct if char s[21];
is defined, but then you have two different "magic numbers" in source, 20 and 21. And the second bug is, even if you have correct length test, the (s[i]!='t')
will execute ahead of i
validation, so at the last character you will have out-of-bounds access.
Anyway, that C be written in C in a bit more "assembly-like" way like this:
i=0;
while(true) { // Your "b while" is doing this already
if (20 < i) break; // test length first, to avoid s[21] (out of bounds)
if ('t' == s[i]) break; // test for "terminator" character
//^^ Yoda notation, to catch typo like (s[i]='t') as error
d[i]=c[i];
++i; // pre-increment form is more accurate to your intent
// As you don't need original value after incrementation
}
// breaks will jump here.
This should be easy to rewrite in assembly, try it...
edit: and your original assembly is not "while", but "do-while", i.e. copy of first byte will execute under all circumstances, which is not what the C example is doing.
edit2: meanwhile of course this assumes you know the boolean logic algebra, as every programmer has to. I.e. you know that:
!(A && B) <=> (!A) || (!B)
Upvotes: 1
Reputation: 239714
So, you've already successfully inverted one of the conditions and used it to jump out of the loop. Does it occur to you that you can do the same for the other?
li $t1,0 # counter for string
li $s0,'t' # chararacter to end copy
li $s1,20 # count to end copy
while: lbu $t0,string($t1) # load a character
sb $t0,copy($t1) # copy character
beq $t0,$s0,end # if character to end copy then exit loop
bgt $t1,$s1,end # if count exceeds limit then exit loop
addi $t1,$t1,1 # increment counter
b while # repeat while loop
Upvotes: 1