1

Using GCC, compiling for 32-bit Intel architecture, with .intel_syntax noprefix. Let's suppose I have the following .data section:

A: .int 0x1, 0x2

What is the difference between the following, when used as an operand: A, [A], offset A? Also, what is the difference when [..] is used on a register and on a memory label?

The difference between writing the register simply and putting it into [..] was answered here well.

  • What assembler? If it's MASM, see [Confusing brackets in MASM32](https://stackoverflow.com/a/25130189). `A` and `[A]` are equivalent. Actually *that* much is true for GAS `.intel_syntax` as well. – Peter Cordes May 06 '20 at 16:34
  • I use gcc and compile for 32-bit intel architecture. – Balázs Börcsök May 06 '20 at 16:36
  • 1
    assembly language is specific to the assembler not the target. so while an assembler may have only one solution various solutions include [a], byte ptr a, (a), #a and variations on those themes. Depends on the author of the assembler and their preferences, sometimes the syntax in the processor documentation is used, sometimes not. Or it also has happened that the pseudocode in the documentation for the processor has changed over time. some of the syntax depending on the isa as well, can use labels or registers some are registers only – old_timer May 06 '20 at 17:16
  • 1
    what did you find when you tried it and examined the output of your specific assembler? please post all of your work and a complete minimal example of the problem. – old_timer May 06 '20 at 17:18

1 Answers1

1

Let me give you a brief explanation.
[] brackets mean something like "do not work with the content, but with the address". When used labelled DATA, you can omit them (it depends on your assembler's syntax, but in MASM it definitely works like that). Why? There is no way of working with data in memory directly; instead, you just work with a data somewhere in memory (on some address). So no disambiguity can happen, you always work with data on address. When you use them with registers, it's a quite different story:

MOV EAX, 10

simply loads 10 (0x0000000A) in EAX register. You work directly with the register. But:

MOV EAX, 666
MOV BYTE PTR [EAX], 77

loads 77 into memory adress 666. The BYTE PTR directive is necessary, because assembler doesn't know if it should use 1, 2, 4 etc. bytes. The [EAX] says "do not work with EAX, instead, work with ADDRESS (memory location) contained in EAX.

If you want to find out a difference between [VAR], VAR and OFFSET VAR, try to step-by-step this code:

.DATA
VAR DWORD 77

.CODE
    MOV EAX, VAR
    MOV EBX, OFFSET VAR
    MOV ECX, [VAR]
    MOV EDX, OFFSET [VAR]

You will clearly see the difference.

  • 1
    *So no disambiguity can happen,* - That wasn't actually the only choice for syntax design. NASM makes the opposite choice, where `mov eax, symbol` is *always* a mov-immediate with the symbol address. (Like `mov eax, OFFSET symbol` in MASM / GAS .intel_syntax.) Note that your `mov eax, 10` has an immediate source, not a register source, and you were just talking about sources, not destinations. In GAS intel-syntax, `mov reg, 123` is a mov-immediate instead of a load from that absolute address. (Unlike AT&T syntax where `mov 123, %eax` *is* a load, `mov $123, %eax` is mov-immediate). – Peter Cordes May 06 '20 at 19:10
  • 1
    One nice feature of NASM syntax (which AT&T also has, but GAS .intel-syntax / and especially MASM itself don't have) is that you can always tell what kind of instruction it is without looking at whether `symbol` is an EQU constant or a label / other symbol. No brackets in NASM means it's definitely a load. In GAS .intel_syntax, it's an immediate if the symbol was `.equ` defined before this instruction, or a memory operand if defined after. That's pretty horrible IMO. [Distinguishing memory from constant in GNU as .intel\_syntax](https://stackoverflow.com/a/39360636) – Peter Cordes May 06 '20 at 19:14
  • I wanted to make the example as simple as possible (thus I used loading of immediates). However, thanks for explanation! I have worked just with MASM (because it is supported by VS)... – Tomáš Chabada May 06 '20 at 19:17
  • Your examples are fine, it's just the text that makes some statements that seem incorrect. It's an arbitrary choice what `mov eax, symbol` does, so IMO it would be clearer to just explain that it's a load in MASM-like syntaxes without trying to justify that as the only possible choice. – Peter Cordes May 06 '20 at 19:53
  • 1
    Typo in my 2nd comment: no brackets in NASM means it's *not* a load, instead an immediate. – Peter Cordes Dec 07 '20 at 12:44