我正在写一个程序,它读入一个字符串,并计算它的长度,以便在程序中使用,这是我目前所拥有的。
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
的分支一样?我现在遇到了一个分段错误。如果有任何提示或指示,我将不胜感激。
(For参考,这是我的整个程序。它还没有完成,我只需要过去计算长度继续到其他部分)。
.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"
1条答案
按热度按时间h9vpoimq1#
我不确定你使用的是什么汇编程序,但我可以说你并不总是正确地使用
BL
。BL
是“分支with link”,它实际上是一条“call”指令,在分支之前用所需的返回地址覆盖链接寄存器。有时你会正确地使用它(BL printf
),有时候不是(BL Loop
,当你的意思只是B Loop
时)。另请注意,到'Loop'标签的第一个分支是不必要的,因为它只是到下一条指令的分支,并且您实际上并没有递增长度计数器(您是在给它加0!)。
我对您的循环片段的建议如下:
请注意循环分支是无条件的,并且在循环开始附近使用条件分支来转义它。
while
循环顶部的条件在每个循环开始时计算,如果不满足,则会导致分支到循环的末尾,就像上面的汇编语言代码一样。