臂组件仅在长度为12的弦上为垃圾

时间:2018-11-22 06:15:48

标签: assembly raspberry-pi arm

在覆盆子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。忽略数字,它们是已分配内存的十进制地址

1 个答案:

答案 0 :(得分:1)

按照惯例,字符串以零字节(称为“终止字符”)终止。

调用HashMap时,将获得字符串中的字符数,但不包括标记其结尾的终止字符。这会导致两个问题:

  • 循环复制字符串时,并不复制终止字符。因此,您的字符串将在内存中的下一个字节(恰好为零)处结束,该字节可以在任何地方。您会看到行为不确定的结果:没有理由为什么当其他数字起作用时12个字符不起作用,这仅是您的特定情况造成的。
  • 如果要添加终止符,则可能会溢出目标字符串缓冲区,因为对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-r3malloc之类的库函数,则可能会再次遇到未定义的行为。)