#assembly #file-io #nasm #scanf
#сборка #файловый ввод-вывод #nasm #scanf
Вопрос:
Я пытаюсь прочитать 3 значения из файла с форматом в виде целого символьного пробела integer. Например:
5, 3
В этом точном формате, т.е. без пробелов после 5, без пробелов после запятой и без пробелов после 3.
Я успешно вызвал fopen, чтобы открыть файл, и я использовал fgetc для доступа к тому же файлу и печати его содержимого. Теперь я пытаюсь использовать fscanf ()
Я читал, что для вызова функции C из сборки вам нужно поместить параметры в стек в обратном порядке, ниже приведен мой код для этого
lea eax, [xValue]
push eax
lea eax, [comma]
push eax
lea eax, [yValue]
push eax
mov eax, [format] ;defined as [format db "%d %c %d", 0] in the data section
push eax
mov eax, ebx ; move handle to file into eax
push eax
call _fscanf
На данный момент я предполагаю, что вышесказанное эквивалентно:
fscanf(fp, "%d %c %d", amp;yValue, amp;comma, amp;xValue);
Если это эквивалентно приведенному выше, как мне получить доступ к прочитанным значениям? Я знаю, что у меня правильный доступ к файлу, поскольку я смог распечатать отдельные символы, вызвав fgetc, но для наглядности ниже приведен мой код для открытия файла
mov eax, fileMode
push eax
mov eax, fileName
push eax
call _fopen
mov ebx, eax ;store file pointer
Любая помощь / совет высоко ценятся. Спасибо.
Отредактировано для добавления…
Ответ предоставил решение. Публикую приведенный ниже код для всех, у кого есть эта проблема.
section .data
fname db "data.txt",0
mode db "r",0 ;;set file mode for reading
format db "%d%c %d", 0
;;--- end of the data section -----------------------------------------------;;
section .bss
c resd 1
y resd 1
x resd 1
fp resb 1
section .text
extern _fopen
global _main
_main:
push ebp
mov ebp,esp
mov eax, mode
push eax
mov eax, fname
push eax
call _fopen
mov [fp] eax ;store file pointer
lea eax, [y]
push eax
lea eax, [c]
push eax
lea eax, [x]
push eax
lea eax, [format]
push eax
mov eax, [fp]
push eax
call _fscanf
;at this point x, y and c has the data
mov eax,0
mov esp,ebp
pop ebp
ret
Ответ №1:
Я думаю, что ваша строка формата scanf () неверна. Должно быть «%d%c %d». Почему вас вообще волнует запятая? Почему бы просто не использовать «%d, %d» и исключить переменную через запятую.
Кроме того, вы пытаетесь загрузить eax со значением из первых байтов [format], вам нужно нажать указатель на format .
Наконец, вам не нужны скобки вокруг адресов памяти, если только ваш ассемблер не странный, вы вводите неправильные адреса.
lea eax, xvalue
push eax
lea eax, yValue
push eax
lea eax, format
push eax
call _fscanf
Теперь у вас должны быть нужные значения в xvalue и yvalue
Комментарии:
1. Когда я попробовал lea eax, xvalue nasm выдает мне следующую ошибку «недопустимая комбинация кода операции и операндов»
2. это нормально, просто так работает ассемблер, используйте скобки