I have a string, and I want to loop it to count the length of the string.
main:
MOV R1, #0
loop:
CMP R1, #10
BGT loop
ADD R1, #1
B loop_end
loop_end:
string: .asciz "Hello World\n"
CodePudding user response:
The pattern for a while-do loop in C is as follows:
while ( condition ) {
???
}
And in assembly the same pattern:
loop1:
if ( ! condition ) goto loop1End;
???
goto loop1;
loop1End:
If you follow the pattern of while, your while loop will run the same in C as in assembly.
Compare this pattern to the code you've posted.
Further, strings are variable length data structures, and as such, they are stored in memory. A strlen
function needs to load from memory in order to examine the individual bytes for their value.
C-style Strings terminate with a nul-character, '\0'. #10 is a newline character, and if you find one in your string, that is part of the string and there are potentially more characters beyond that.
CodePudding user response:
The code is comparing R1 to ten and branches back to loop if R1 is more than ten. Else, it increments R1 by 1 and branches (unconditionally) to the end of the loop. This is not right. Also, it is not clear why the code is comparing R1 to ten. If you need the code to work for any length of string, then it should check for the null character at the end of the string.
Another thing, string is a keyword/directive name in ARM. So call the string something else like foo, for example.
The logic should look like this: Get a character, if null, branch to end, else increment pointer (to get the next character) and loop for another iteration.
Depending on the version of ARM you have, it could look something like this:
foo: .asciz "Hello World\n"
mov R3, #0 //setup a counter
ldr R1, =[foo] //R1 has the address of the string
loop:
ldrb R2, [R1] //get a byte from that address
cmp R2, #0 //compare the byte value to the null
character
beq loop_end //branch to end of loop if true
//otherwise
add R1, #1 //increment the pointer
add R3, #1 //increment counter
b loop
loop_end:
//rest of the code