создать заголовочный файл для сканирования целых чисел без использования stdio.h (scanf) - PullRequest
1 голос
/ 07 августа 2011

Мне нужно создать файл заголовка для функции int read_int(), которая сканирует целое число и возвращает его, не используя scanf.

У меня есть некоторые знания по расширенному asm.Я точно не знаю, как сканировать элементы с помощью функции asm__volatile .

вниз - это код, который я использовал для печати целого числа (без использования stdio.h). Работая идеально

__asm__ __volatile__ (
    "movl $4, %%eax \n\t"
    "movl $1, %%ebx \n\t"
    "int $128 \n\t"
    :
    :"c"(buff), "d"(bytes)
) ; // $4: write, $1: on stdin

1 Ответ

1 голос
/ 07 августа 2011

Какая часть причиняет вам неприятности?Чтение данных из стандартного ввода выполняется с помощью системного вызова read (список системных вызовов для x86 linux см. здесь ), аналогично тому, как вы используете write для печати:

int my_fgets(char* s, int size, int fd) {
    int nread;
    __asm__ __volatile__(
        "int $0x80\n\t"
    : "=a" (nread)
    : "a" (3), "b" (fd), "c" (s), "d" (size)
    );
    return nread;
}

Реализация собственной getchar (по вашему желанию) с использованием вышеуказанной функции прямолинейна.

Если это «сканирование» и чтение целого числа, с которым у вас возникли проблемы,это можно сделать с помощью указанной выше функции:

#define MY_STDIN 0
int read_int() {
    char buffer[256];
    int nr, number;

    nr = my_fgets(buffer, sizeof(buffer), MY_STDIN);
    if (nr < 1) {
        /* error */
    }
    buffer[nr - 1] = 0; // overwrite newline

    __asm__ __volatile__(
        "mov $0, %0\n\t" // initialize result to zero
        "1:\n\t" // inner loop
        "movzx (%%esi), %%eax\n\t" // load character
        "inc %%esi\n\t" // increment pointer
        "and %%eax, %%eax\n\t"
        "jz 2f\n\t" // if character is NUL, done
        "sub $'0', %%eax\n\t" // subtract '0' from character
        "add %%eax, %0\n\t" // add to result
        "jmp 1b\n\t" // loop
        "2:\n\t"
    : "=q" (number)
    : "S" (buffer)
    : "eax" // clobber eax
    );
    return number;
}

Поскольку эта функция предназначена для домашней работы, указанная выше функция неполна и будет работать только для чисел от 0 до 9, хотя ее расширение должно быть тривиальным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...