内联asm类型不匹配

时间:2016-10-05 19:36:00

标签: 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;
}

1 个答案:

答案 0 :(得分:1)

正如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 for i386。

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

我也打算不使用内联asm。我不确定你为什么不想使用系统调用,但是你只是为了让自己陷入悲痛。