Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 内联asm类型不匹配_Linux_Gcc_64 Bit - Fatal编程技术网

Linux 内联asm类型不匹配

Linux 内联asm类型不匹配,linux,gcc,64-bit,Linux,Gcc,64 Bit,我正在尝试为64位linux系统调用自己的读取系统。但它总是告诉我我的类型不好。编译器是否试图间接寻址buf?我觉得我的输入限制搞砸了。我只需要buf在%2的地址 错误: 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(

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

错误:

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;
}
要了解这一点,请查看i386的

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


我还将为不使用内联asm做一个宣传。我不知道你为什么不想只使用系统调用,但你只是在为自己设置悲伤。

如果
int
是32位整数,你会得到这些错误。我正在编写一个简单的shell程序,仅用于学术目的。另外,gcc似乎无法进一步优化我的代码,而不会弄糟一些东西。在AMD64 abi中,我找不到关于哪些寄存器被某些系统调用阻塞的任何信息。你能告诉我自己学习的方向吗?谢谢你抽出时间!啊哈,我刚刚在A.2.1中找到了它,我发现学习低层次的细节确实有助于我在更高层次上更好地编程。我发现这些琐碎的程序对我很有启发。使用内联asm确实有助于理解编译器和操作系统中的工作原理。我担心的是,人们试图在生产代码中使用它。我自己对内联asm的最初努力是基于(错误的)信念,即我可以“调整事情”,从最内部的循环中挤出更多的性能。不,是真的!但我相信你的努力没有白费。你一定学到了很多。我也在asm中编写了shell,我尝试使toupper函数没有分支,但不知道如何实现它。如果你有时间,请评论一下,我会非常感激的!