вызов fscanf в сборке с использованием nasm

#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. это нормально, просто так работает ассемблер, используйте скобки