创建一个头文件来扫描整数而不使用stdio.h(scanf)

时间:2011-08-07 06:17:11

标签: c assembly

我需要为函数int read_int()创建一个头文件,它扫描整数并返回它,而不使用scanf

我对扩展的asm有一些了解。我不知道如何通过函数 asm__volatile 扫描元素。

down是用于打印整数的代码(不使用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 个答案:

答案 0 :(得分:1)

哪一部分会给你带来麻烦?从标准输入读取数据是使用read系统调用完成的(请参阅here获取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,但扩展它应该是微不足道的。