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 很奇怪。它接受movbmovw 的AT&T 语法,但不接受movl【参考方案2】:

不只是 https://defuse.ca/online-x86-assembler.htm 这样奇怪:它只是在 .intel_syntax noprefix 模式下使用 GAS。

(所以你想要mov dword ptr [0x08048c5f], 0xdeadbeef 就像@Joachim 所说的那样)


但有趣的是,在 Intel 语法模式下,GNU 汇编器接受 movbmovw,但不接受 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 内联汇编为调用者生成的指令与纯汇编函数不同

C指针原理-AT&T汇编

NASM TO GAS:对应于 GAS 中的 resw

刚开始使用汇编(GAS),并且在这个短代码中有分段错误

在 x86 汇编代码(GAS 语法)中有效乘以 2 的幂而不影响标志

gcc生成含有C信息的汇编