ARM汇编:从STDIN获取字符串

4

我目前正在上一门计算机科学课程,我们刚刚开始在树莓派上使用ARM汇编语言进行编程。这证明是相当困难的,所以我想知道是否有人能够帮助我。我的当前任务是从stdin中取出一个字符串(使用scanf),然后计算出其中的字符数,并返回该数字(因此基本上要实现自己的strlen)。我已经通过以下代码掌握了基本思路:

.section        .rodata
promptWord:
    .ascii  "Enter a word: \000"

readWord:
    .ascii  "%s\000"

printLength:
    .ascii  "Word length is %d characters.\n\000"

.section .data
    .align 2

    .comm   word,4,4
    .text

addrword:  .word word
addrPromptWord: .word promptWord
addrReadWord: .word readWord
addrPrintLength: .word printLength



    .global  main
                                    /* s: r0 */

main:
    stmfd   sp!, {fp, lr}       /* Save pc, lr, r4*/

    ldr r0, addrPromptWord
    bl  printf

    ldr r0, addrReadWord
    ldr r1, addrword
    bl  scanf

    ldr r0, addrword
    ldr r0, [r0]

    mov r1, #0
skip:
    ldrb    r2,[r0]                 /* r2 <- *a */
    mov     r3,#0
    cmp     r2,r3
    beq     endskip                 /* if (*a == 0) jump endskip */
    mov     r3,#1
    add     r0,r0,r3                /* a++ */
    add     r1, r1, r3              /* len++ */
    bal     skip                    /* go to skip */

endskip:
    mov r0, r1                      /* Return len */

    ldmfd   sp!, {fp, pc}  

我假设问题出在代码的.data部分,因为(我猜)那不是对齐字符串的正确方式。非常感谢您的帮助。谢谢!


你读过这个吗? - Scott Solmer
1
.comm word,4,4 只会分配 4 个字节。对于指针来说很好,但如果字符串更长,它可能会崩溃。尝试使用 .space 128 并使用比 word 更好的名称,如 userString。您可以省略 al 并编写 b skip。此外,您可以在进入和退出时保存所有寄存器 stmfd sp!,{r4-r12,lr}ldmfd sp!,{r4-r12,pc}。您的汇编程序不使用它们,但是“C”代码可能会使用... 我认为这不是您的问题。 - artless noise
可能会有所帮助,告诉我们哪些地方出了问题。汇编器是否报错?代码是否崩溃?在哪里崩溃?等等。 - doron
2个回答

1
为什么不编写一个C程序来完成相同的任务并运行?
gcc -S file.c

你会看到编译器如何在file.s(由gcc生成的汇编代码文件)中处理它。即使您不理解file.s中的某些行,它也会将您带到ARM汇编手册的正确位置。
这不是直接回答您的问题。但遗憾的是我无法评论您的帖子,否则我会这样做。

1
我认为你在使用scanf部分遇到了问题。
你需要向scanf(在r1中)提供字符串输入的地址。获取的内存大小将来自堆栈。由于ARM ABI使用完整下降堆栈,您需要从当前堆栈指针减去所需的字节数,只需确保这是字对齐的即可。然后,您可以将新的sp复制到r1中,然后在scanf中使用它。
你可能不需要addr的东西在你的数据段中。你可能需要指定你的代码进入文本部分,并且没有什么阻止你把所有的只读数据也放在文本部分。如果你使用PC相对地址,这将非常有帮助。
希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接