我目前正在参加CS课程,我们刚刚开始在Raspberry Pi上使用ARM Assembly。它被证明是非常困难的,并且想知道是否有人可以提供帮助。我当前的任务是从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部分,因为(我假设)这不是对齐字符串的正确方法。任何帮助深表感谢。谢谢!
答案 0 :(得分:1)
为什么不写一个C程序做同样的事情,然后运行
gcc -S file.c
您将看到编译器如何在file.s中处理它(由gcc生成的汇编代码)。即使您不理解file.s中的某些行,它也会引导您到正确的arm组装手册
这不是您问题的直接答案。但伤心的是我无法评论你的帖子,否则我会这样做。
答案 1 :(得分:1)
我认为您在scanf
部分遇到问题。
您需要为scanf
(在r1中)提供字符串输入所需的地址。要获得的大量内存将来自堆栈。由于ARM ABI使用完全降序堆栈,因此从当前堆栈指针中减去所需的字节数,只需确保这是字对齐的。然后,您可以将新sp复制到r1,然后将其用于scanf。
您可能不需要数据部分中的addr内容。您可能需要指定代码进入文本部分,并且没有什么可以阻止您将所有只读数据放在文本部分中。如果您使用PC相对地址,这将非常有用。
希望这会有所帮助。