我正在使用https://defuse.ca/online-x86-assembler.htm#disassembly将x86指令组装到机器代码中。 (编者注:它在.intel_syntax noprefix
模式下使用GAS。)
下面的代码抛出Error: no such instruction: `movl $0xdeadbeef,0x08048c5f'
movl $0xdeadbeef,0x08048c5f
但是下面的汇编代码工作正常
movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f
您似乎正在为您的movl使用AT&T语法,但您链接的页面表明它需要Intel语法。
如果我理解你的意图正确,那么你想要的指令的正确语法就是;
MOV DWORD PTR ds:0x08048c5f, 0xdeadbeef
(在地址0x08048c5f存储双字值0xdeadbeef)
这不仅仅是https://defuse.ca/online-x86-assembler.htm这样的奇怪:它只是在.intel_syntax noprefix
模式中使用GAS。
(所以你想要mov dword ptr [0x08048c5f], 0xdeadbeef
作为@Joachim说)
但有趣的是,在英特尔语法模式下,GNU汇编程序接受movb
和movw
,但不接受movl
!!
但是,它并没有将它们解释为AT&T语法。在Intel-syntax中,目标位于左侧,$0xdeadbeef
是有效的符号名称,因为它以$
开头,而不是数字。 GAS的.intel_syntax
模式类似于MASM,其中(如AT&T语法)裸符号名称是内存操作数。
令人惊讶的是,movb
被接受为mov
指定字节操作数大小,但是一旦我们超过它,movb $0xdeadbeef, 0x08048c5f
就相当于mov byte ptr [label], 0x5f
。
请注意,0x08048c5f
常量(您打算作为目标地址)是直接源操作数。它被截断为8位。 GAS警告这一点,但在线汇编程序会隐藏警告,这些警告可以帮助您找出这种奇怪之处。 :(
.intel_syntax noprefix
movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f
在我的Linux桌面上使用as --version
= GNU汇编程序(GNU Binutils)2.31.1
$ as -32 syntax.s -o syntax.o
as -32 -o syntax.o syntax.s
syntax.s: Assembler messages:
syntax.s:3: Warning: 134515807 shortened to 95
syntax.s:4: Warning: 134515807 shortened to 35935
$ objdump -drwC -Matt syntax.o
syntax.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: c6 05 00 00 00 00 5f movb $0x5f,0x0 2: R_386_32 $0xdeadbeef
7: 66 c7 05 00 00 00 00 5f 8c movw $0x8c5f,0x0 a: R_386_32 $0xdeadbeef
$ ld -melf_i386 syntax.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
ld: syntax.o:(.text+0x2): undefined reference to `$0xdeadbeef'
ld: syntax.o:(.text+0xa): undefined reference to `$0xdeadbeef'
试图链接,并要求objdump
显示-r
中的.o
重新定位,明确表示$0xdeadbeef
被视为符号名称,与我使用my_label
相反没有什么不同。
只需使用在线汇编程序,就可以更加难以理解,因为它只显示机器代码。目的地地址的00 00 00 00
是您发生奇怪事情的唯一线索。
我不知道为什么接受movb和movw,但movl并不意味着dword操作数大小。
它可能是一个GAS错误,它们都被接受了。