Как вызвать fgets в сборке x86? - PullRequest
4 голосов
/ 11 сентября 2010

Согласно документации для fgets(), функция принимает три параметра:

  • char * - строка, которая будет содержать ввод
  • int - целое число, представляющее максимальное количество символов для чтения
  • FILE * - FILE * в поток для чтения из

У меня нет проблем с вызовом функции. Я просто push три параметра в стеке, вызываю функцию и увеличиваю ESP на 12.

Моя проблема с параметром # 3. Что должно быть передано как FILE * для стандартного ввода? В C я могу просто использовать stdin, но я не знаю, каков эквивалент в сборке x86.


Обновление: Я использую NASM в Linux.

Ответы [ 4 ]

5 голосов
/ 11 сентября 2010

Проблема с stdin заключается в том, что это макрос, который расширяется до чего-то не только платформо-зависимого, но, скорее всего, труднодоступного из сборки вручную.Если вы готовы пожертвовать stdio и использовать вместо этого вызовы POSIX, stdin совпадает с известным файловым дескриптором # 0.Поэтому вы можете передать 0 на read и получить почти то, что искали.Я уверен, что это более дружественный ассемблер, чем макрос stdin C.

1 голос
/ 11 сентября 2010

Если сборка представляет собой подпрограмму для кода C / C ++, большинство сред выполнения предоставляют средства прямого доступа к переменной stdin через внешнюю ссылку.Проверьте заголовочный файл stdio.h (или, возможно, все, что он включает).Обычные подозреваемые - это переменные с именем __stdin или массив FILE * с именем типа __stdio[], где первые 3 элемента - это stdin, stdout и stderr.

Если C используется в качестве библиотекидля какого-то другого языка (например, ассемблера) вам нужно будет самому вызывать инициализирующий модуль Си.Это может быть сложно определить.Если бы я понятия не имел, как, я написал бы программу типа C "hello world" и прошел бы через нее с помощью отладчика, чтобы увидеть, как она устанавливает stdin.

Другой совершенно другой подход - это вызовfopen() чтобы получить ФАЙЛ * файла для чтения.

0 голосов
/ 11 сентября 2010

Это чистая сборка, использующая libc.- Джордж Эдисон

Тогда ответ будет полностью зависеть от системы разработки и операционной системы.Libc не нацелен на поддержку такого рода вещей.

Даже если бы вы могли выяснить, как сделать этот тип вызова, стандартный указатель указывает на довольно сложную, зависящую от ОС или системы разработки структуру данных FILE, котораяинициализируется libc с использованием подпрограмм, которые вызываются до запуска main ().Таким образом, в чистом виде вам тоже придется все это делать.Именно из-за этого простая программа «Hello world» на языке C создает достаточно хороший размер исполняемого файла на любой платформе.

Если вы пишете простую C-программу, которая читает некоторую информацию из stdin, а затем разбираетвсе это и точно понять, что он делает, у вас будет хорошее начало в этом.Но это не будет быстрым, и то, что вы узнаете, безусловно, не будет переносимым, скажем, с Visual Studio в Windows на gcc в Linux.

0 голосов
/ 11 сентября 2010

stdin - это концепция, которая существует только в C. Его определение зависит от вашего компилятора C и библиотеки, и из-за макросов и т. П. Может быть очень трудно вызвать ассемблер.

Одна вещь, которую вы можете попробовать, это трактовать ее так, как если бы stdin была глобальной переменной размера регистра. Загрузите его в регистр (используя любые соглашения о распределении имен, которые использует ваш компилятор C), затем поместите его в стек. Если это не работает, вам нужно изучить исходный код библиотеки C, чтобы увидеть, как он работает.

В качестве альтернативы, вы можете использовать низкоуровневые вызовы операционной системы, которые могут быть более пригодными для использования ассемблером - однако, поскольку вы не указали свою ОС, трудно быть более конкретным.

...