x86_64 无法将 64 位值添加到 rax,“'add' 上的操作数不匹配”

Posted

技术标签:

【中文标题】x86_64 无法将 64 位值添加到 rax,“\'add\' 上的操作数不匹配”【英文标题】:x86_64 Cannot add 64 bit value to rax, "operand mismatch on 'add'"x86_64 无法将 64 位值添加到 rax,“'add' 上的操作数不匹配” 【发布时间】:2019-10-06 15:48:03 【问题描述】:

我正在尝试组装一些 64 位代码,但组装失败:

addq $0xffffff7fc0005000, %rax

出现错误:

`add' 的错误操作数类型不匹配

第一个操作数是一个 64 位的值,而后者是一个可以很好地组装的寄存器。该指令前面有一个.code64 伪操作。我正在组装

x86_64-elf-as test.s -o test.o --64

至于汇编器本身,当使用--version 调用时,它会返回:

GNU assembler (GNU Binutils) 2.32
Copyright (C) 2019 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-elf'.

【问题讨论】:

嗯,这是一个令人困惑的错误消息与一个超出范围/不可编码立即数的警告。我称之为可用性错误。他们很容易写出一条错误消息,不会让你去 SO 询问有关它的问题。 我只是好奇。您是否正在编写具有更高半内核的 64 位操作系统? 我问是因为之前您问过一个关于确保某些内容的大小为 0x200 字节的问题。当时我相信您可能一直在编写自定义引导加载程序。在这个问题中,我注意到您使用的是 binutils 的交叉编译器版本。我发现有趣的是 addq $0xffffff7fc0005000 几乎看起来就像有人在最后 2GiB 虚拟地址空间中编写一个更高半的内核时会做的事情。如果这是真的,那么addq $0xffffff7fc0005000 是错误的,可能应该是规范地址$0xffffffffc0005000 addq $0xffffffffc0005000, %rax 不会出错,因为 $0xffffffffc0005000 可以表示为 32 位有符号值 $0xc0005000,当符号扩展到 64 位时也是 $0xffffffffc0005000。 (0xc0005000 的第 31 位最高位是值 1,因此当符号扩展时,64 位值中的所有位都取值为 1)。 Can I add 64bit constants to 64bit registers? 是同一问题的 NASM 版本。 (NASM 有更好的错误信息:warning: signed dword immediate exceeds bounds 【参考方案1】:

第一个操作数是一个 64 位的值,后一个是一个寄存器,应该可以很好地组装。

不应该,add 的 64 位版本可以采用 8 位或 32 位符号扩展立即数,但不能采用 64 位立即数,这在 x64 中通常很少见。这可以通过查看英特尔软件开发人员手册或其他各种地方来验证,例如this online copy of the ADD lemma。

唯一可以采用完整 64 位立即数(不是 32 位符号扩展)的指令是 mov(或 movabs,因为 GAS 喜欢称此变体,尽管具有较大的数字常量 mov $0x123456789abc, %rcx will pick the necessary encoding,不要截断数字)。

通常你会 mov 一个 64 位立即数到一个寄存器中,然后使用它。

另一种选择是将值放入内存中,并在带有内存操作数的add 中使用它。

【讨论】:

以上是关于x86_64 无法将 64 位值添加到 rax,“'add' 上的操作数不匹配”的主要内容,如果未能解决你的问题,请参考以下文章

x86_64寄存器rax/eax/ax/al覆盖完整的寄存器内容[重复]

x86-64的条件跳转如何工作?

x86/x64 添加置换寻址

movl on x64 with GCC inline

架构 x86_64 的重复符号

警告“将架构 arm64 映射到 x86_64”是啥意思?