【问题标题】:GAS Assembler - Fgets function SegFaultsGAS 汇编器 - Fgets 函数 SegFaults
【发布时间】:2020-09-29 06:56:31
【问题描述】:

当我尝试使用 fgets 时,这个简单的程序会出现段错误。我尝试过使用读取功能而不是

       ldr r1, =input_string
       mov r3, #80
       mov r0, #0
       bl read

但这失败了

read(0, 0x21044, 3201061676) = -1 EINVAL(无效参数)

所以我正在尝试使用 fgets。我的字符串缓冲区似乎有问题?

.data

.balign 4
message1:       .asciz "Please type a string: \n"

.balign 4
input_string:
        .asciz ""
        .zero 80

return: .word 0

.text
.global main

main:
        push {lr}
        ldr r0, =message1
        bl printf
        mov r0, #0
        bl fflush

        ldr r0, =input_string
        mov r1, #80
        mov r2, #0

        bl fgets

        mov r0, r1
        bl printf

        pop {lr}
        bx lr
.end


.global printf
.global read
.global fgets

编辑: 我尝试按照 cmets 中给出的示例使用标准输入,但这无法编译说: 错误:立即表达式需要 # 前缀 -- `mov r2,=stdin'

    ldr r0, =input_string
    mov r1,   #80
    mov r2,   =stdin
    ldr r2,   [r2]

似乎没有像 C 中那样为“stdin”预定义的宏,那么我如何告诉它使用 stdin?

【问题讨论】:

  • 当您为FILE*fgets 的第三个参数传递NULL 指针时,您期望什么? man7.org/linux/man-pages/man3/fgets.3.html read 采用 Unix 文件描述符(作为第一个 arg),fgets 采用 stdio FILE* 作为最后一个 arg。
  • Counting Characters in a String in armV7 展示了如何使用fgets
  • 刚刚注意到您的read 调用传递了r3 中的长度,这是一个不存在的第四个参数,而不是r2(第三个参数)。此外,在 asm 中,内联 svc 系统调用指令而不是调用 libc 包装器是相当常见的。 (使用 R7,IIRC 中的索书号)。但你不需要这样做。
  • 我将字符串缓冲区传递为 arg1,将字节数传递为 arg2,并且我认为是标准输入,但您链接到的示例似乎显示了预定义的标准输入。但是当我尝试它时它不起作用。 ldr r0, =input_string mov r1, #80 mov r2, =stdin ldr r2, [r2]
  • 是的,FILE *stdin 是一个全局指针变量,由 libc 启动代码初始化以指向 FILE 结构。我本以为它会起作用,至少如果你做了ldr r2, =stdin 而不是mov。查看 C 编译器输出 (godbolt.org)

标签: assembly arm fgets gnu-assembler


【解决方案1】:
   ldr r0,=input_string
   mov r1,#80
   ldr r2,=stdin
   ldr r2,[r2]
   bl fgets

答案是使用LDR和stdin

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 2011-07-11
    • 2013-03-13
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多