I'm using https://defuse.ca/online-x86-assembler.htm#disassembly to assemble x86 instructions to machine code. (Editor's note: it uses GAS in .intel_syntax noprefix
mode.)
The below code throws Error: no such instruction: `movl $0xdeadbeef,0x08048c5f'
movl $0xdeadbeef,0x08048c5f
But the following assembly code works fine
movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f
You seem to be using AT&T syntax for your movl, but the page you link states that it wants Intel syntax.
If I understand your intention correctly, the correct syntax for the instruction you want would be;
MOV DWORD PTR ds:0x08048c5f, 0xdeadbeef
(which stores the double word value 0xdeadbeef at address 0x08048c5f)
It's not just https://defuse.ca/online-x86-assembler.htm that's weird like this: it just uses GAS in .intel_syntax noprefix
mode.
(So you want mov dword ptr [0x08048c5f], 0xdeadbeef
as @Joachim says)
But the interesting part here is that the GNU assembler accepts movb
and movw
, but not movl
, when in Intel-syntax mode!!
However, it's not interpreting them as AT&T syntax. In Intel-syntax, the destination is on the left, and $0xdeadbeef
is a valid symbol name because it starts with a $
, not a digit. GAS's .intel_syntax
mode is MASM-like, where (like AT&T syntax) a bare symbol name is a memory operand.
The surprising thing is that movb
is accepted as specifying byte operand-size for mov
, but once we get past that, movb $0xdeadbeef, 0x08048c5f
is equivalent to mov byte ptr [label], 0x5f
.
Note that the 0x08048c5f
constant (which you intended to be the destination address) is the immediate source operand. And it's truncated to 8 bits. GAS warns about this, but the online assembler hides the warnings that would have helped you figure out this weirdness. :(
.intel_syntax noprefix
movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f
On my Linux desktop with 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'
Trying to link, and asking objdump
to show relocations with -r
in the .o
, make it clear that that $0xdeadbeef
is being treated as a symbol name, no different than if I'd used my_label
instead.
With just the online assembler, it would be a lot harder to figure this out because it only shows you the machine code. The 00 00 00 00
for the destination address is your only clue that something weird happened.
I have no idea why movb and movw are accepted, but movl doesn't imply dword operand-size.
It's probably a GAS bug that they're accepted at all.
User contributions licensed under CC BY-SA 3.0