movl on x64 with GCC inline
Posted
技术标签:
【中文标题】movl on x64 with GCC inline【英文标题】: 【发布时间】:2014-04-21 09:56:22 【问题描述】:在 x64 中,我想在给定 64 位地址的情况下从内存中读取 32 位值。这似乎相当琐碎,只需使用movl
指令即可。
但是,使用 GCC 内联“扩展”汇编程序,我无法完成这项工作。以下是我的代码:
unsigned row = 0;
__asm __volatile__
(
"again:"
"movzbq (%[px]), %%rax\n"
"movzwq (%[symbols],%%rax,2), %%rax\n"
"add %[table], %%rax\n"
"movl (%%rax,%[row],4), %[row]\n" /* <------------ */
"cmp %[row], %[match_limit]; jb end;\n"
"inc %[px]\n"
"cmp %[px_end], %[px]; jb again\n"
"end:\n"
: "=r" (row), "=r" (px)
: [row] "0" (row),
[px] "1" (px),
[px_end] "r" (px_end),
[symbols] "r" (char_to_symbol),
[table] "r" (table),
[match_limit] "r" (match_limit)
: "%rax"
);
这给了我“指令操作数无效”的错误消息。如果我将movl
更改为movslq
,它会做我想做的事情(只要我的号码是31 位或更少)。换句话说,我想要的是movzlq
行为——除非它不存在,因为在 x64 中所有移动都将零扩展。
我对 GCC 的扩展内联语法非常陌生。我如何在这个位置获得movl
?
【问题讨论】:
这是 AT&T 语法 -- 目的地是%[row]
,而不是 %rax
您似乎正试图从一个内存移动到另一个内存。 mov
无法做到这一点。
【参考方案1】:
您需要对(低位)32 位寄存器使用k
操作数修饰符,例如,
movl (%%rax,%0,4), %k0
我不确定在哪里可以找到这些的最终列表。在these 答案和this 教程中有一些。
【讨论】:
您链接到的 SO 问题的答案实际上仍然是正确的 AFAIK - 唯一的“规范”列表在 gcc 的架构定义文件中,raw.github.com/mirrors/gcc/trunk/gcc/config/i386/i386.md以上是关于movl on x64 with GCC inline的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL 11 install with jit on CentOS 7.5 X64
Mysql Innodb Deadlock on delete with Primary Keys IN 语句
[Javascript] Use JavaScript's for-in Loop on Objects with Prototypes