2017-09-03 51 views
1

我是装配新手,过去几天一直在网上寻求帮助,但无济于事。使用Scanf ARM组件的分段故障

.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 

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

编辑:添加了注释的代码的建议和固定复制错误(scanf函数 - > BL的scanf)

+1

使用调试器,特别是如果你希望别人帮助注释你的代码。无论如何,'scanf'甚至不应该编译,看起来像一个复制粘贴错误,你可能有'bl scanf'那里。请确保您向我们展示您实际使用的代码。 'ldr r1,[r1]'也没有意义,当然你也没有评论你想要做什么,所以无法为你解决。请注意,'r1'被调用者保存,所以'scanf'将会破坏它。你似乎并不知道scanf是如何在C中工作的(你甚至没有为返回值传递一个缓冲区)。 – Jester

+0

你的字符串等工作在C?问题是汇编语言还是调用函数?把问题分成两半。 –

+0

在'bl scanf'出现错误,并且'bl printf'按照预期的方式正确输出(在调试器中)?由于我甚至对'ldr r0,addr_prompt'感到困惑,我认为只有'ldr r0,prompt'才能加载符号'prompt'的地址,但这又可能是ARM汇编语言,我不知道知道,这可能需要一些关键字用于直接加载。通过'addr_prompt:.word提示符'你的间接性仍然很可能是多余的,并且不清楚你为什么使用它(对于这个简短的例子没有明显的目的)。 – Ped7g

回答

0

需要一个缓冲器/存储器,用于存储输入数据。从树莓派Raspbian

.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 

输出:

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

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

非常感谢!我不知道需要缓冲区或如何实现它。只是为了一些额外的澄清和理解; '.space'后面的'80',这是指什么? –

+0

缓冲区长度为80个字符。 – bstipe