在覆盆子pi上的arm程序集中编写链接列表时,遇到一个奇怪的问题。我的链表适用于除长度为12的字符串以外的所有字符串。它在长度为12的所有字符串的末尾显示一个垃圾字符,我不知道为什么
感谢您的帮助
这是我正在使用的输入函数,它将地址输出到R0中的malloc字符串,并且似乎对于所有长度为12的字符串都可以正确运行:
.equ BUFSIZE2,256
.data
inputbuf2: .ds BUFSIZE2
prompt: .asciz "Enter: "
p1: .word 0
input:
push {R1,R2,R5,R14}
mov R0,#0
bl v_ascz @ prints string in R1
ldr R1,=inputbuf2
mov R2,#BUFSIZE2
bl c_ascz @ does service call for input, returns in R1
bl v_ascz
bl v_nl
bl strlen @ returns string length of R1 into R0
sub R0,#1
mov R5,R0
bl alloc
bl store
ldr R0,=p1
ldr R0,[R0]
pop {R1,R2,R5,R14}
bx LR
alloc:
push {R0-R4,R14}
bl malloc
ldr R1,=p1
str R0,[R1]
pop {R0-R4,R14}
bx LR
store:
push {R1-R4,R14}
mov R2,#0 @ index
ldr R4,=p1
ldr R4,[R4]
loop: ldrb R3,[R1],#1
strb R3,[R4],#1
add R2,#1
cmp R2,R5
blt loop
mov R3,#0
strb R3,[R4] @ store null at end of string
pop {R1-R4,R14}
bx LR
.end
这是我正在使用的链表添加节点功能。它分配8个字节,并将地址存储到前四个数据中,并将地址存储到后四个节点中的下一个节点:
.global list_add
@ R1 = addr of head
@ R2 = addr of tail
@ R3 = data
.data
node: .word 0
list_add:
push {R1-R4,R14}
bl alloc
push {R2}
ldr R2,[R2]
cmp R2,#0
pop {R2}
beq first_node
@ normal add
ldr R4,=node
ldr R4,[R4]
push {R2}
ldr R2,[R2] @ R2 = tail node
str R4,[R2,#4] @ R2 next ptr = node
pop {R2}
str R4,[R2] @ tail = node
str R3,[R4] @ node data = first addr of data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4,R14}
bx LR
first_node:
push {R1-R4}
ldr R4,=node
ldr R4,[R4]
str R4,[R1] @ head = node
str R4,[R2] @ tail = node
str R3,[R4] @ node data = data
mov R3,#0
str R3,[R4,#4]
pop {R1-R4}
pop {R1-R4,R14}
bx LR
alloc:
push {R1-R3,R14}
mov R0,#8
bl malloc
ldr R1,=node
str R0,[R1]
ldr R1,[R1]
mov R3,#0
str R3,[R1]
str R3,[R1,#4]
pop {R1-R3,R14}
bx LR
在我女友的狗的周围,随机地添加了一堆随机字符串,这就是output。忽略数字,它们是已分配内存的十进制地址
答案 0 :(得分:1)
按照惯例,字符串以零字节(称为“终止字符”)终止。
调用HashMap
时,将获得字符串中的字符数,但不包括标记其结尾的终止字符。这会导致两个问题:
strlen
的调用也没有为终止符分配足够的空间。虽然我在这里,但我也可能会将您引荐给ARM ABI,尤其是the part about the procedure call standard。尽管ABI并不排除使用malloc
作为中间值,但是这些寄存器(以及r0-r3
)被“调用”,因此通常使用r12
进行中间计算。函数通常必须使用堆栈来保留r4-r11
。因此,您使用r4-r11
来保存函数参数(指向r5
)与ABI相反,因此您的store
函数将无法从符合ABI的代码中调用。如果您的呼叫者也遵守ABI,则无需在多个位置推送/弹出store
。还要注意的是,ABI需要在不同转换单元中的函数调用之间进行8字节堆栈对齐,因此,养成推入和弹出偶数个寄存器以保持此状态的习惯是一个好主意。 (例如,如果在不确保8字节对齐的情况下调用r1-r3
或malloc
之类的库函数,则可能会再次遇到未定义的行为。)