โปรแกรมง่ายๆ นี้ segfaults เมื่อฉันพยายามใช้ fgets ฉันได้ลองใช้ฟังก์ชั่นการอ่านแทนด้วย
ldr r1, =input_string
mov r3, #80
mov r0, #0
bl 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
แก้ไข: ฉันพยายามใช้ stdin ตามตัวอย่างที่ให้ไว้ในความคิดเห็น แต่ไม่สามารถคอมไพล์ได้โดยบอกว่า: ข้อผิดพลาด: การแสดงออกทันทีต้องใช้คำนำหน้า # -- `mov r2,=stdin'
ldr r0, =input_string mov r1, #80 mov r2, =stdin ldr r2, [r2]
ดูเหมือนจะไม่มีมาโครที่กำหนดไว้ล่วงหน้าสำหรับ stdin เหมือนใน C ดังนั้นฉันจะบอกให้มันใช้ stdin ได้อย่างไร
NULL
สำหรับFILE*
หาเรื่องที่ 3 ของfgets
man7.org/linux/man-pages/man3/fgets.3 htmlread
รับตัวอธิบายไฟล์ Unix (เป็นข้อโต้แย้งแรก),fgets
รับ stdioFILE*
เป็นข้อโต้แย้งสุดท้าย - person Peter Cordes   schedule 29.09.2020fgets
- person Peter Cordes   schedule 29.09.2020read
ของคุณส่งผ่านความยาวในr3
ซึ่งเป็น arg ที่ 4 ที่ไม่มีอยู่จริง แทนที่จะเป็นr2
(arg ที่ 3) นอกจากนี้ ใน asm เป็นเรื่องปกติที่จะอินไลน์คำสั่งsvc
system-call แทนที่จะเรียก libc wrapper (โดยมีหมายเลขโทรศัพท์อยู่ใน R7, IIRC) แต่คุณไม่จำเป็นต้องทำอย่างนั้น - person Peter Cordes   schedule 29.09.2020FILE *stdin
เป็นตัวแปรตัวชี้ร่วมที่เริ่มต้นโดยโค้ดเริ่มต้น libc เพื่อชี้ไปที่โครงสร้างFILE
ฉันคาดหวังว่ามันจะได้ผล อย่างน้อยถ้าคุณทำldr r2, =stdin
ไม่ใช่mov
ดูเอาต์พุตคอมไพเลอร์ C (godbolt.org) - person Peter Cordes   schedule 29.09.2020