defuse.ca 在线 GAS 汇编器接受 movb 和 movw 的 AT&T 语法,但不接受 movl?
Posted
技术标签:
【中文标题】defuse.ca 在线 GAS 汇编器接受 movb 和 movw 的 AT&T 语法,但不接受 movl?【英文标题】:defuse.ca online GAS assembler accepts AT&T syntax for movb and movw, but not movl? 【发布时间】:2014-10-13 04:18:13 【问题描述】:我正在使用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
【问题讨论】:
当你执行代码时你没有得到那个错误;当您尝试汇编/编译该代码时,您可能会遇到该错误。显示更多您的来源。 听起来您可能使用了错误的汇编器/编译器。提供更多信息。 x86 对移动字节、双字节、四字节和 8 字节有不同的指令。你必须告诉汇编器 something 以便它知道目标的大小以及选择哪条指令。您的特定汇编程序的“movb”似乎表示“移动字节”,同样适用于“movw”。 “mov”显然对您的特定汇编程序没有任何意义。在对这个特定主题提出更多问题之前,请阅读汇编器手册。 阅读您的汇编手册? 【参考方案1】:您似乎在为您的 movl 使用 AT&T 语法,但您链接的页面声明它需要 Intel 语法。
如果我正确理解您的意图,您想要的指令的正确语法是;
MOV DWORD PTR ds:0x08048c5f, 0xdeadbeef
(将双字值 0xdeadbeef 存储在地址 0x08048c5f)
【讨论】:
defuse.ca/online-x86-assembler.htm#disassembly 很奇怪。它接受movb
和movw
的AT&T 语法,但不接受movl
。【参考方案2】:
不只是 https://defuse.ca/online-x86-assembler.htm 这样奇怪:它只是在 .intel_syntax noprefix
模式下使用 GAS。
(所以你想要mov dword ptr [0x08048c5f], 0xdeadbeef
就像@Joachim 所说的那样)
但有趣的是,在 Intel 语法模式下,GNU 汇编器接受 movb
和 movw
,但不接受 movl
!!
但是,不将它们解释为 AT&T 语法。在 Intel 语法中,目标位于左侧,$0xdeadbeef
是一个有效的符号名称,因为它以 $
开头,而不是数字。 GAS 的.intel_syntax
模式类似于 MASM,其中(类似于 AT&T 语法)一个裸符号名称是一个内存操作数。
令人惊讶的是movb
被接受为为mov
指定字节操作数大小,但是一旦我们超过了这一点,movb $0xdeadbeef, 0x08048c5f
就等同于mov byte ptr [label], 0x5f
。 p>
请注意,0x08048c5f
常量(您打算作为目标地址)是直接源操作数。它被截断为 8 位。 GAS 对此发出警告,但在线汇编程序隐藏了可以帮助您找出这种怪异的警告。 :(
.intel_syntax noprefix
movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f
在我的 Linux 桌面上使用 as --version
= GNU assembler (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
在.o
中显示带有-r
的重定位,明确表明$0xdeadbeef
被视为符号名称,与我使用@ 时没有什么不同改为 987654342@。
仅使用在线汇编器,要弄清楚这一点要困难得多,因为它只向您显示机器代码。目标地址的00 00 00 00
是您唯一可以知道发生了奇怪事情的线索。
我不知道为什么 movb 和 movw 被接受,但 movl 并不意味着双字操作数大小。
这可能是他们完全接受的 GAS 错误。
【讨论】:
以上是关于defuse.ca 在线 GAS 汇编器接受 movb 和 movw 的 AT&T 语法,但不接受 movl?的主要内容,如果未能解决你的问题,请参考以下文章
为啥包装在函数中的 GAS 内联汇编为调用者生成的指令与纯汇编函数不同