问题
I have an instruction written in Intel syntax (using gas as my assembler) that looks like this:
mov rdx, msg_size
...
msg: .ascii "Hello, world!\n"
.set msg_size, . - msg
but that mov instruction is being assembled to mov 0xe,%rdx
, rather than mov $0xe,%rdx
, as I would expect. How should I write the first instruction (or the definition of msg_size
) to get the expected behavior?
回答1:
In GAS .intel_syntax noprefix
mode:
OFFSET symbol
works like AT&T$symbol
. This is somewhat like MASM.symbol
works like AT&Tsymbol
(i.e. a dereference).[symbol]
is always an effective-address, never an immediate, in GAS and NASM/YASM.LEA
doesn't load from the address, but it still uses the memory-operand machine encoding. (That's why it uses the same syntax).
Tip: if you know the AT&T syntax, or the NASM syntax, for something, use that to produce the encoding you want and then disassemble with objdump -Mintel
to find out the right syntax for .intel_syntax noprefx
.
BTW, no open-source projects that I'm aware of contain GAS intel_syntax source code. If they use gas, they use AT&T syntax. Otherwise they use NASM/YASM. (You sometimes also see MSVC inline asm in open source projects).
GNU as .intel_syntax noprefix
mode is somewhat like MASM, except there's no magic that depends on how symbols are defined.
mov rdx, symbol
is always a load. A symbol's value is its address. i.e. using .set creates (or modifies) a symbol that behaves exactly the same as putting a label on something.
(unless symbol
was defined as an assemble-time constant with symbol=123
, or .equ symbol, 123
, then it's a mov-immediate.)
mov rdx, OFFSET symbol
will assemble to mov r/m64, imm32
. I forget if intel-syntax mode lets mov
assemble to movabs r64, imm64
with large operands, but that's irrelevant because static data/code addresses are always in the low 2GiB of virtual address space, so they fit in 32-bit sign-extended immediates.
(This makes it safe to write mov edx, OFFSET symbol
, and in fact you should always do that or use lea rdx, [rip + symbol]
, never sign-extended 32-bit immediate unless you're writing code that will be loaded into the high 2GB of virtual address space.)
来源:https://stackoverflow.com/questions/39355188/distinguishing-memory-from-constant-in-gnu-as-intel-syntax