Эта простая программа дает сбой, когда я пытаюсь использовать 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
РЕДАКТИРОВАТЬ: я попытался использовать стандартный ввод в соответствии с примером, приведенным в комментариях, но это не удалось скомпилировать, говоря: Ошибка: для немедленного выражения требуется префикс # -- `mov r2,=stdin'
ldr r0, =input_string mov r1, #80 mov r2, =stdin ldr r2, [r2]
Кажется, нет предопределенного макроса для стандартного ввода, как в C, так как мне сказать ему использовать стандартный ввод?
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
, несуществующем 4-м аргументе, а не вr2
(3-й аргумент). Кроме того, в ассемблере довольно часто встраивается инструкция системного вызоваsvc
вместо вызова оболочки libc. (С номером вызова в 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