我正在尝试编写一个程序,该程序读取字符串并计算其长度,以供以后在程序中使用。到目前为止,这就是我所拥有的。
ldr x0, =stringread
ldr x1, =strbuffer //string to be analyzed
bl scanf
mov x9, #0 //initialize length = 0
bl Loop
Loop:
ldrb w11, [x1, x9] //load w11 with the x9th value of the string in x1
cbnz w11, increment_length //until a 0 appears, continue iterating
//thru string while incrementing length
/* what to put here to break the loop once zero is reached?*/
increment_length:
add x9, x9, #0
bl Loop
我不确定如何打破这个循环。我会分支到另一个只是用来打破循环的分支吗?如标记为zero_reached
的分支中一样?我目前遇到细分错误。任何提示或指示,将不胜感激。
(作为参考,这是我的整个程序。它尚未完成,我只需要过去计算长度即可继续到其他部分)。
.data
outformat: .asciz "%c"
flush: .asciz "\n"
stringread: .asciz "%s"
lengthread: .asciz "%d"
strbuffer: .space 100
lenbuffer: .space 8
.text
.global main
main:
ldr x0, =prompt
mov x1, x0
bl printf
ldr x0, =stringread
ldr x1, =strbuffer
bl scanf
mov x9, #0 //length
bl Loop
Loop:
ldrb w11, [x1, x9]
cmp w11, #0
bne increment_length
add x9, x9, #1
increment_length:
add x9, x9, #0
bl Loop
#Change length to length-1
sub x0, x0, #1
#Move string address to x1
ldr x1, =strbuffer
#Starting index for reverse
mov x2, #0
#Branch to reverse, setting return address
bl reverse
#Flush the stdout buffer
ldr x0, =flush
bl printf
#Exit the program
b exit
reverse: #In reverse we want to maintain
#x0 is length-1
#x1 is memory location where string is
#x2 is index
subs x3, x2, x0
#If we haven't reached the last index, recurse
b.lt recurse
base: #We've reached the end of the string. Print!
ldr x0, =outformat
#We need to keep x1 around because that's the string address!
#Also bl will overwrite return address, so store that too
stp x30, x1, [sp, #-16]!
ldrb w1, [x1, x2]
bl printf
ldp x30, x1, [sp], #16
#Go back and start executing at the return
#address that we stored
br x30
recurse: #First we store the frame pointer(x29) and
#link register(x30)
sub sp, sp, #16
str x29, [sp, #0]
str x30, [sp, #8]
#Move our frame pointer
add x29, sp, #8
#Make room for the index on the stack
sub sp, sp, #16
#Store it with respect to the frame pointer
str x2, [x29, #-16]
add x2, x2, #1
#Branch and link to original function.
bl reverse
#Back from other recursion, so load in our index
end_rec:
ldr x2, [x29, #-16]
#Print the char!
stp x30, x1, [sp, #-16]!
ldr x0, =outformat
ldrb w1, [x1, x2]
bl printf
ldp x30, x1, [sp], #16
#Clear off stack space used to hold index
add sp, sp, #16
#Load in fp and lr
ldr x29, [sp, #0]
ldr x30, [sp, #8]
#Clear off the stack space used to hold fp and lr
add sp, sp, #16
#Return to correct location in execution
br x30
exit:
mov x0, #0
mov x8, #93
svc #0
.section .data
prompt:
.asciz "input a string\n"
答案 0 :(得分:0)
我不确定您使用的是哪个汇编程序,但是我可以说您并不总是正确地使用BL
。 BL
是“带链接的分支”,实际上是一条“调用”指令,在分支之前用所需的返回地址覆盖链接寄存器。有时候您正确使用(BL printf
,有时没有正确使用(BL Loop
,当您的意思仅仅是B Loop
时)。
还请注意,“ Loop”标签的第一个分支是不必要的,因为它只是分支到下一条指令,并且您实际上并没有增加长度计数器(您要向其添加0!)。
我对您的循环代码段的建议如下:
ldr x0, =stringread
ldr x1, =strbuffer // String to be analyzed
bl scanf
mov x9, #0 // Initialize length = 0
Loop:
ldrb w11, [x1, x9] // Load w11 with the x9th value of the string in x1
cbz w11, LoopEnd // Until a 0 appears, continue iterating
add x9, x9, #1 // Increment x9
b Loop
LoopEnd: // Continue from here
请注意,循环分支是无条件的,并且在循环开始处附近使用条件分支来对其进行转义。如果出现类似
的代码,这大约是C编译器将生成的内容char * buffer = strbuffer;
int index = 0;
while (buffer[index] != 0) {
++index;
}
while
循环顶部的条件在每个循环的开始进行评估,并且如果不满足,则会导致分支跳转到循环结束,就像上面的汇编语言代码一样。