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

标签 c assembly

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

我对扩展汇编有一些了解。我不完全知道如何通过函数 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

最佳答案

哪个部分给你带来了麻烦?使用 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,尽管扩展它应该是微不足道的。

关于c - 创建一个头文件来扫描整数而不使用 stdio.h(scanf),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6971105/

相关文章:

c - gcc - 在 bss 中编写和执行代码 - 设置权限标志

c - 将结构中的所有变量设置为零/一

C - 如何从文件中获取没有数字、特殊字符(、.?&)的单词?

c - C中的无限循环BUG

c - 如何在 Linux 中测量时间?

c - 从 BIOS 加载 Linux 操作系统内核

c - 独立于时间在 C 中播种 rand()

c++ - C/C++ 中的高级指针类型转换

assembly - AVX VMOVDQA 比两个 SSE MOVDQA 慢?

assembly - 如何简化汇编翻译右移 32 异或绝对数和值