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'
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
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
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