GAS Assembler - Fungsi Fget SegFaults

Program sederhana ini mengalami kesalahan saat saya mencoba menggunakan fgets. Saya telah mencoba menggunakan fungsi baca dengan

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

tapi ini gagal dengan

read(0, 0x21044, 3201061676) = -1 EINVAL (Argumen tidak valid)

Jadi saya mencoba menggunakan fgets. Sepertinya ada yang salah dengan buffer string saya?

.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

EDIT: Saya mencoba menggunakan stdin sesuai contoh yang diberikan dalam komentar, tetapi ini gagal dikompilasi dengan mengatakan: Kesalahan: ekspresi langsung memerlukan # awalan -- `mov r2,=stdin'

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

Sepertinya tidak ada makro yang ditentukan sebelumnya untuk stdin seperti di C, jadi bagaimana cara menyuruhnya menggunakan stdin?


person Rick Dearman    schedule 29.09.2020    source sumber
comment
Apa yang Anda harapkan ketika Anda memberikan pointer NULL untuk FILE* argumen ke-3 dari fgets? man7.org/linux/man-pages/man3/fgets.3. html read menggunakan deskriptor file Unix (sebagai argumen pertama), fgets menggunakan stdio FILE* sebagai argumen terakhir.   -  person Peter Cordes    schedule 29.09.2020
comment
Menghitung Karakter dalam String di armV7 menunjukkan cara menggunakan fgets.   -  person Peter Cordes    schedule 29.09.2020
comment
Perhatikan saja bahwa panggilan read Anda melewati panjang r3, argumen ke-4 yang tidak ada, bukan r2 (argumen ke-3). Selain itu, di asm, cukup umum untuk memasukkan instruksi panggilan sistem svc alih-alih memanggil pembungkus libc. (Dengan nomor panggilan di R7, IIRC). Tapi Anda tidak perlu melakukan itu.   -  person Peter Cordes    schedule 29.09.2020
comment
Saya meneruskan buffer string sebagai arg1, jumlah gigitan sebagai arg2, dan yang saya pikir adalah stdin, tetapi contoh yang Anda tautkan sepertinya menunjukkan stdin yang telah ditentukan sebelumnya. Namun ketika saya mencobanya tidak berhasil. ldr r0, =input_string gerakan r1, #80 gerakan r2, =stdin ldr r2, [r2]   -  person Rick Dearman    schedule 29.09.2020
comment
Ya, FILE *stdin adalah variabel penunjuk global yang diinisialisasi oleh kode startup libc untuk menunjuk pada struct FILE. Saya berharap itu berhasil, setidaknya jika Anda melakukan ldr r2, =stdin bukan mov. Lihatlah keluaran kompiler C (godbolt.org)   -  person Peter Cordes    schedule 29.09.2020
comment
Terima kasih! Saya tahu saya menggunakan instruksi yang salah (mov bukannya ldr), tepat sebelum saya melihat komentar Anda. Terima kasih atas semua bantuannya.   -  person Rick Dearman    schedule 29.09.2020


Jawaban (1)


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

Jawabannya adalah dengan menggunakan LDR dan stdin

person Rick Dearman    schedule 29.09.2020