linux - 内联汇编类型不匹配

标签 linux gcc 64-bit

我正在尝试为 64 位 Linux 系统创建自己的读取系统调用。但它一直告诉我我的类型不好。编译器是否试图间接寻址 buf?我有一种感觉,我搞砸了我的输入限制。我只需要位于 %2 的 buf 地址。

错误:

test.c: Assembler messages:
test.c:28: Error: operand type mismatch for `movq'


static int myread(int fd, char *buf, int size) {
    register int bytes;

    asm(
    "movq $0, %%rax\n"

    "movq %1, %%rdi\n"
    "movq %2, %%rsi\n"
    "movq %3, %%rdx\n"
    "syscall\n"

    "movq %%rax, %0"

    : "=r" (bytes)
    : "m" (fd), "m" (buf), "m" (size)
    : "%rax", "%rdi", "%rsi", "%rdx"
    );

    return bytes;
}

最佳答案

正如 Mystical 所说,不匹配错误来自于您在 32 位整数(如 fd 和 size)上使用 movq(用于 64 位值)。

但除此之外,这段代码确实效率低下并且存在微妙(但危险)的缺陷。也许更像这样:

static int myread(int fd, char *buf, int size) {
    register int bytes;

    asm(
       "syscall"

    : "=a" (bytes)
    : "D" (fd), "S" (buf), "d" (size), "0" (0)
    : "rcx", "r11", "memory", "cc"
    );

    return bytes;
}

要了解这一点,请查看 machine constraints对于 i386。

请注意,系统调用会破坏 rcx 和 r11 寄存器。不通知编译器您正在更改这些值可能会导致非常奇怪的问题。而且问题不会发生在系统调用上,而是下游的一百行。

我还将宣传不使用内联汇编。我不确定您为什么不想只使用系统调用,但您只是在为悲伤做好准备。

关于linux - 内联汇编类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39882271/

相关文章:

c - pthread 不等待互斥锁 threadFinished

linux - 使用 usbfs 在 usb 设备上调用 ioctl() 不起作用

python - 使用一些arm-gcc交叉编译PyZMQ

vb6 - Visual Basic 6程序可以在64位计算机上运行吗?

C# - 如何在 Windows 64 位上获取程序文件 (x86)

c++ - 在 Ubuntu Eee 上编译内核需要什么?

linux - CentOS 7 无法解析 Zabbix 触发器

c - 与 gcc 静态链接时如何只包含使用过的符号?

linux - ldd -r -v如何向文件添加版本符号?

windows - Microsoft Windows 64 位应用程序开发最佳实践安装文件夹