我只是通过在gas体系结构上组装(与objdump)和反汇编(与amd64)而发现了一条奇怪的指令。 >
然后,在amd64编译它之后(我正在使用以下命令行:gas),gcc -m64 -march=i686 -c -o myobjectfile myassemblycode.s给出了以下代码:

mov 0x89abcdef, %al


我的问题是我在英特尔汇编手册中找不到任何objdumpmovabs(甚至没有movab指令)。

所以,我在做梦吗?这条指令是什么意思?我的猜测是它是GNU binutils的一个怪癖,但我不确定。

PS:我精确检查了该指令的拼写,因此肯定不是mova指令。

评论

我认为前5个字节是a0 ef cd ab 89,而不是a0 df ce ab 89

stackoverflow.com/questions/19415184/…

另请参见MOVABS指令何时引入?

#1 楼

这是gas的官方文档,引用了相关部分:


在AT&T语法中,内存操作数的大小由指令助记符的最后一个
字符确定。 bw
lq的助记符后缀指定字节(8位),字(16位),长(32位)和
四字(64位)内存引用。英特尔语法通过在内存操作数(而不是指令助记符)前添加
byte ptrword ptrdword ptrqword ptr来实现此目的。因此,Intel mov al, byte ptr foo在AT&T语法中为movb foo, %al

在64位代码中,可以使用movabs编码具有64位位移或立即数的mov指令。


阅读最后一句话。

注意:通过Google运算符inurl找到,搜索movabs inurl:sourceware.org/binutils/

评论


我查看了加油站手册,但找不到正确的部分。非常感谢0xC0000022L! :-)

–恐怖
13年8月12日在19:53

如何将32位数字移动到al中?

–phuclv
2013年9月25日在6:24

@LưuVĩnhPhúc:好吧,您只能承受损失,但这与我的回答或问题无关,因此您最好将其作为一个新问题提出。

– 0xC0000022L♦
2013年9月25日在7:17

有趣的是,即使在disassembly-flavor = intel中,gdb也为我提供了48个b8 字节作为movabs rax,

–俄罗斯
14-10-30在10:31



#2 楼

movabs用于绝对数据移动,既可以将任意64位常量加载到寄存器中,也可以从64位地址将数据加载到寄存器中。

来源:http:// www。 ucw.cz/~hubicka/papers/amd64/node1.html

#3 楼

如果您发现自己经常解密AT&T语法x86 / x64汇编程序,则Solaris手册可能会有所帮助:x86汇编语言参考手册。

评论


很好的可下载参考,感谢igorsk的链接

– blabb
13年8月13日9:00

#4 楼

我注意到GAS将

movq 
movabs 0x80000000, %rax
x80000000, %rax

转换为

q4312078q

,但小于0x80000000运动的值不会转换为movabs
即,不会将movq movabs disasx7fffffff, %rbxx7fffffff, $rbx转换为movabsqx80000000。您可以在GDB中使用movq反汇编命令进行验证。

原因可能是q4312079q超出了32位带符号正数范围,需要转换为64位整数。因此,GAS会将较大的数字转换为64位长的整数,因此使用q4312079q指令代替q4312079q指令,后者的直接来源仅限于32位常量。

评论


这是错误的movq $ 0x80000000,%rax将立即数0x80000000移入rax,而movabs 0x80000000,%rax将地址0x80000000的四字加载到rax

–phuclv
18年8月8日在6:30