【问题标题】:Segmentation Fault Using Scanf ARM Assembly使用 Scanf ARM 程序集的分段错误
【发布时间】:2017-09-05 00:24:28
【问题描述】:

我是组装新手,过去几天一直在互联网上寻求帮助,但无济于事。

.data

format: .asciz "%s"
string: .asciz "Output: %s\n"

prompt: .asciz ">"

.text
.global main
.main:

    ldr r0, addr_prompt     /*loading address of prompt message in r0*/
    bl printf               /*calling printf*/   

    ldr r0, addr_format     /*loading first parameter of scanf*/
    ldr r1, addr_string     /*loading second parameter of scanf*/
    bl scanf                /*calling scanf*/

    /*below I am trying to print out the user 
    input from scanf*/

    ldr r1, [r1]            
    bl printf

    mov r7, #1
    swi 0

addr_prompt: .word prompt
addr_format: .word format
addr_string: .word string

运行时,它会给出“分段错误”错误。有人可以告诉我我做错了什么,任何帮助将不胜感激。

编辑:按照建议将 cmets 添加到代码中并修复了复制错误 (scanf -> bl scanf)

【问题讨论】:

  • 使用调试器并注释您的代码,特别是如果您希望其他人提供帮助。无论如何,scanf 甚至不应该编译,看起来像一个复制粘贴错误,你可能在那里有bl scanf。请确保向我们展示您实际使用的代码。 ldr r1, [r1] 也没有任何意义,当然你没有评论你想要它做什么,所以不能为你修复它。请注意,r1 是调用者保存的,因此scanf 将销毁它。您似乎根本不知道 scanf 在 C 中是如何工作的(您甚至没有为返回值传递缓冲区)。
  • 你的字符串等在 C 中工作吗?问题是您的汇编语言还是对函数的调用?把问题分成两半。
  • bl scanf 是否有故障,bl printf 是否按预期工作,输出正确(在调试器中)?因为我什至对ldr r0, addr_prompt 感到困惑,我希望那个是ldr r0, prompt 只是为了加载符号prompt 的地址,但这可能是我还不知道的ARM 汇编语言,这可能需要一些用于直接加载的关键字。您通过addr_prompt: .word prompt 进行的间接访问仍然很可能是多余的,并且不清楚您使用它的原因(对于如此简短的示例没有明显的目的)。

标签: assembly arm printf scanf


【解决方案1】:

需要一个缓冲区/存储来存储输入数据。

.data

format: .asciz "%s"

string: .asciz "Output: %s\n"
prompt: .asciz ">"

storage: .space 80          @ --- added buffer

.text
.global main
main:                       @ --- removed .

    ldr r0, addr_prompt     /*loading address of prompt message in r0*/
    bl printf               /*calling printf*/

    ldr r0, addr_format     /*loading first parameter of scanf*/
    ldr r1, addr_storage    @ --- location to write data from input
    bl scanf                /*calling scanf*/

    /*below I am trying to print out the user
    input from scanf*/

    ldr r1, addr_storage    @ --- data location
    ldr r0, addr_string     @ --- printf format
    bl printf

    mov r0, #0              @ --- good return code
    mov r7, #1
    swi 0

addr_prompt: .word prompt
addr_format: .word format
addr_string: .word string
addr_storage: .word storage @ --- address of buffer

树莓派 Raspbian 的输出:

as -o printf10.o printf10.s
gcc -o printf10 printf10.o

./printf10; echo $?
>Hello
Output: Hello
0

【讨论】:

  • 非常感谢!我不知道需要缓冲区或如何实现它。只是为了一些额外的澄清和理解; .space 后面的 80 是什么意思?
  • 缓冲区长度为 80 个字符。
猜你喜欢
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多