92

To me, Intel syntax is much easier to read. If I go traipsing through assembly forest concentrating only on Intel syntax, will I miss anything? Is there any reason I would want to switch to AT&T (outside of being able to read others' AT&T assembly)? My first clue is that gdb uses AT&T by default.

If this matters, my focus is only on any relation assembly and syntax may have to Linux/BSD and the C language.

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
oevna
  • 1,196
  • 1
  • 10
  • 10

7 Answers7

83

There is really no advantage to one over the other. I agree though that Intel syntax is much easier to read. Keep in mind that, AFAIK, all GNU tools have the option to use Intel syntax also.

It looks like you can make GDB use Intel syntax with this:

set disassembly-flavor intel

GCC can do Intel syntax with -masm=intel.

Zifre
  • 24,944
  • 8
  • 81
  • 102
  • 18
    as well, echo set dis intel >> ~/.gdbinit – oevna Jun 09 '09 at 21:38
  • 9
    How is AT&T syntax less readable? I find having size suffixes on operands more consise than having "dword". Is there something else I'm missing? – Hawken Mar 25 '12 at 14:11
  • 55
    `lea -0x30(%rcx,%rax,8),%eax` is convoluted ATT for `lea eax,[rcx+rax*8-0x30]`. The use of + and * really helps in Intel style. – jørgensen Apr 01 '12 at 18:35
  • 1
    I'd like to see what Hawken has to say about this example. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ May 25 '12 at 17:12
  • 9
    I see their "convolution" as equal but unidentical: if ATT is opaque, then Intel is ambiguous. Although infix arithmetic is more familiar to algebra students, it is not obvious from the syntax that there are exactly 4 arguments to the operation, or that only one of them may be multiplied, and in neither case is it clear that the multiplier must be a power of 2. – bug Sep 07 '12 at 01:40
  • 10
    @Hawken I find AT&T's suffixes much better than Intel's "ptr"s because you always specify it and it **really** reduces the amount of mistakes (at least for me). About the rest (for example the $ and % symbols).. yeah.. they're not pleasant, and that's the point, but they do have an advantage: it's explicit and once again reduces mistakes. I'd say that one is comfortable for reading (Intel) and the second for writing (AT&T). – MasterMastic Dec 27 '12 at 10:43
  • @Ken I personally like the way AT&T's register `%` looks; call me weird ;). The `$` do get occasionally tedious, I'll admit. – Hawken Dec 28 '12 at 03:11
  • @Hawken I still don't get what an immediate value without a $ is. for example movl 23, %eax. What does it store in EAX? I get a segmentation fault before I can see it, so it's probably an issue with the OS (since it assembles just fine). – MasterMastic Dec 28 '12 at 12:39
  • 3
    @Ken in my testing it means the number is evaluated as a memory address instead. So, `movl 4, %eax` is `mov eax,[0x4]` in intel and `movl $4, %eax` means `mov eax,[0x4]`. – Hawken Jan 05 '13 at 23:32
  • @Hawken Ah, I thought so but it seemed not consistent. Thanks! – MasterMastic Jan 06 '13 at 01:12
  • 5
    One of the most annoying feature of AT&T syntax is the reversion of parameters. Other architectures' assembly all have the destination at first, like high level languages' assignment – phuclv Sep 19 '13 at 05:29
  • 2
    @LưuVĩnhPhúc The "reversion" of parameters is *far* from annoying to me. If you think about what you're actually doing, the way AT&T notates it is actually *much* clearer. When you do, e.g., `movb $0, %al`, it's clear that you're moving 0 *to* `al`. Whereas in Intel you have `mov al, 0`, which makes it look like you are moving `al` to 0, which obviously makes no sense. In reality you're moving 0 to `al`, but I end up reading it in the convoluted manner of "move to `al`, this thing (which is zero in this case)." Frankly, I'm not fond of Yoda-speak in my assembly ;) – GDP2 Sep 18 '17 at 07:25
  • 2
    @GDP2 yeah that's what AT&T supporters most often say. It may be easy to read with 2 operands but when you face 3-operand or 4-operand instructions like `add a, b, c` like in AVX512, AVX2 or other RISC architectures then it'll much harder to make sense. `movb $0, %al` looks like assigning al to 0 which obviously make no sense to me. – phuclv Sep 18 '17 at 08:09
  • ... Moreover with `cmp` and `sub` you'll have to reverse the condition for the jump instructions. How about fused-multiply add/sub? How do you think and read `fms a, b, c` when it means `a = a*b - c` or `c = a*b - c` or `c = b*c - a`...? AT&T is not even consistent in its order: x87 instructions aren't reversed. I've never read `mov` as `move` but `mov` like Ivanov or Asimov so I don't think of it as a movement but an assignment. – phuclv Sep 18 '17 at 08:10
  • Frankly if you stick into AT&T then you'll have problem in other architectures. They all use `add a, b, c, d` to indicate `a = b + c + d` or `a = a + b + c + d` – phuclv Sep 18 '17 at 08:15
  • @LưuVĩnhPhúc What exactly do you mean by: "Moreover with `cmp` and `sub` you'll have to reverse the condition for the jump instructions"? Regarding the rest of what you're saying, about multiple operands, other architectures, etc., that is beyond the scope of my argument. I did not consider that issue initially and you have a point there. – GDP2 Sep 18 '17 at 18:13
  • 1
    @GDP2 `if (A > B)` would be naturally rendered like `cmp A, B; ja AgtB` but in AT&T it would be `cmp B, A` which is very confusing. Similarly `sub A, B` means `B = B - A` which makes zero sense – phuclv Sep 19 '17 at 02:58
  • @LưuVĩnhPhúc Regarding subtraction, I view it as "subtract `A` *from* `B` and put that value in `B`." Regarding comparison, I obviously see it in the same way that I see subtraction. I look at the jump condition as simply comparing the result of the comparison / subtraction with the value currently stored in the operand. I.e., when I see `cmpl $0, %eax; jle somewhere`, I read it as "subtract 0 from `eax` and jump to `somewhere` if that result is less than or equal to the value that's currently in `eax`." – GDP2 Sep 19 '17 at 07:09
  • @LưuVĩnhPhúc In my point of view, Intel syntax basically advocates for imagining operator symbols in between operands for the expression to make sense. AT&T more closely resembles the reality of what's going on (imho). – GDP2 Sep 19 '17 at 07:11
45

The primary syntax for the GNU assembler (GAS) is AT&T. Intel syntax is a relatively new addition to it. x86 assembly in the Linux kernel is in AT&T syntax. In the Linux world, it's the common syntax. In the MS world, Intel syntax is more common.

Personally, I hate AT&T syntax. There are plenty of free assemblers (NASM, YASM) along with GAS that support Intel syntax too, so there won't be any problems doing Intel syntax in Linux.

Beyond that, it's just a syntactic difference. The result of both will be the same x86 machine code.

mmx
  • 390,062
  • 84
  • 829
  • 778
  • 26
    Agreed and agreed. It should be a crime to use AT&T syntax, it's counter-intuitive and ugly, why would you want to prefix every single number and register with $ and %, and specify relative addressing in reverse SIB notation, I've been using Intel syntax for two years and still can't see why AT&T even exists. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Nov 21 '09 at 21:37
  • 12
    If you are going to state it in bold at least provide some evidence as to why intel is **so much** better. – Hawken Mar 25 '12 at 14:27
  • 8
    @Hawken Haters gonna hate – Gunther Piez Mar 31 '12 at 18:08
  • 8
    @Hawken Are you suggesting that because he used bold type, he's somehow stating his opinion as fact in a way he wouldn't have been if he'd simply left the bold alone? The question was practically inviting this kind of opinion-led "debate" anyway, presumably why it's now closed! – Elliott Aug 23 '12 at 21:38
  • 1
    How about Intel syntax for ARM? – ceving May 11 '17 at 08:35
  • @L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ What is reverse SIB notation? – PSkocik Dec 28 '18 at 12:23
35

There is really no advantage to one over the other. I disagree though that Intel syntax is much easier to read, because personally I hate Intel syntax. Keep in mind that, AFAIK, all GNU tools have the option to use Intel syntax also.

at&t noprefix                   intel
mov eax, -4(ebp,edx,4)          mov DWORD PTR[-4 +ebp +edx *4], eax
mov eax, -4(ebp)                mov DWORD PTR[-4 +ebp], eax
mov edx, (ecx)                  mov DWORD PTR[ecx], edx
lea (   ,eax,4), eax            lea eax, DWORD PTR[8 + eax*4]
lea (eax,eax,2), eax            lea eax, DWORD PTR[eax*2+eax]

...and it gets more complicated with more complex instructions

'nuff said.

PS: This answer exists mainly for the reason of highlighting (IMHO) weaknesses in some other answers, which are actually not answers, but opinions. And of course this answer in reality is only my humble opinion.

PPS: I do not hate Intel syntax, I just don't care.

Gunther Piez
  • 28,058
  • 6
  • 62
  • 101
  • 20
    I'm terribly confused. Are you implying that at&t syntax never needs to make the word size explicit? Why did you copy my example and add word sizes and the useless PTR thing? Also why did you change my differences to sums with a negative left operand? Is it because that's how the instruction is actually encoded? The user rarely has to care about that really. In every assembler I've used, you can omit the DWORD PTR since the left operand is 32-bit and the right operand has square brackets around it. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Apr 01 '12 at 00:29
  • 12
    Moreover, IDA/ollydbg don't even produce anything as like what you wrote, so, I'm pretty sure there's no problem going from machine code to "nice" intel syntax. So your example seems pretty contrived and something I'd never see except in the most trivial implementation of an assembler or disassembler. On the other hand, the at&t instructions I mock are directly from one of the first paragraphs of a tutorial teaching at&t syntax. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Apr 01 '12 at 00:32
  • 8
    I have come to the conclusion that you are a machine so you prefer a syntax that directly mirrors the bit-encoding of the instruction. (which is what at&t syntax does). I also have a suspicion that people feel more 1337 when they use at&t syntax since it's more obscure, though that's not really an advantage... – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Apr 01 '12 at 00:34
  • 7
    @Longpoke No, AT&T syntax does not need to make the word size explicit if it is clear from the context. Just the same as with intel: You don't need `SOMEWORD PTR[]` if the operand size is clear from the context. But you need it in case of moving an immediate to a memory location (both the `l` from AT&T as the DWORD PTR from Intel). And yes my example is pretty contrived - but so was yours. In case you still don't see why: You left out the unneeded wordsizes on Intel, but have them in AT&T. You choose the operands in a way so that they align nicely in Intel, but don't do so in AT&T. – Gunther Piez Apr 01 '12 at 11:55
  • 2
    @Longpoke I really do not prefer AT&T over Intel. I am using what's there. I agree that AT&T contains way to much `%` (unless you switch them off) and that the occasionally needed DWORD PTR on Intel is really ugly, but other than that I think it's all personal preference. A lot of answers here a very subjective, but maybe thats because the question is actually a subjective. BTW, I didn't downvote you (but I was tempted). I think your answer is bad, because it is subjective, but OTOH is good you are at least giving some examples (although badly chosen). – Gunther Piez Apr 01 '12 at 12:10
  • 2
    I found my examples by looking for "at&t syntax tutorial" on a search engine. They aren't really contrived... you see stuff like this all the time in disassembly. Meanwhile your `mov DWORD PTR[-4 +ebp +edx *4], eax`... I've never seen *anything* produce syntax in that form. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Apr 01 '12 at 13:52
  • 3
    Just try `objdump -M intel` for a start. – Gunther Piez Apr 01 '12 at 14:17
  • 4
    ahh, forgot about `objdump -M intel`. Well that's just ghetto. It's not really intel syntax, though. It's a hack on the at&t syntax parser to make it look like Intel. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Apr 01 '12 at 18:04
  • 3
    +1 for a witty comeback and making a good point. I laughed. – zeboidlund Sep 03 '12 at 03:57
  • 7
    So are you saying `-4(ebp,edx,4)` thing is better than `[4*edx+ebp-4]`? I find the latter more intuitive. – Calmarius Jul 05 '13 at 06:55
  • 5
    @Calmarius No I don't say it is better. I am just saying that by cherry-picking the best (or worst) examples for the syntax you can make one look better than the other - like this has been done in other answers. But it's mainly a matter of taste. I personally adapt to the syntax which is already used in a project, for me its all he same ;-) – Gunther Piez Jul 10 '13 at 08:56
  • 2
    These differences of SIB syntax are trivial compared to operand order. See e.g. `sub eax,ecx`. It's easy to directly translate this Intel-syntax instruction to C statement of `eax-=ecx;` mentally. In AT&T reading of that example code you'd instead have to mentally reverse the order, or read it as `-eax+ecx→ecx` (yeah, that's subtraction...). Same for all other non-commutative operations like `cmp`, `idiv` etc.. – Ruslan Sep 03 '17 at 14:35
  • Self-contradiction is not convincing, impersonally. – FrankHB May 20 '19 at 22:49
  • AT&T noprefix seems like a really terrible idea (and I've *never* seen anyone suggest it, other than this answer); making it easy to confuse readers who sometimes look at NASM or Intel syntax, e.g. `sub eax, ecx` on its own doesn't have any clues that it's not Intel syntax. Clang's built-in assembler doesn't even support it, only AT&T prefix or Intel noprefix. – Peter Cordes Oct 03 '20 at 01:52
  • What I like about AT&T syntax is that addressing modes reflect how they work in machine code, and that indirect jumps use a `*`. I dislike many other things, especially operand order and bare symbol = memory operand, and the design bug of reversing the semantics of some x87 instructions with register operands (`fsubr` vs. `fsub`), and inventing different mnemonics than the Intel manuals, making it confusing for some beginners to look things up. `symbol(%rip)` is actually a pretty decent way to indicate RIP-relative vs. absolute, but means you have to make it explicit in every addressing mode. – Peter Cordes Oct 03 '20 at 02:03
25

It's the "same language", in that it compiles down to the same machine code, has the same opcodes, etc. On the other hand, if you are using GCC at all, you will probably want to learn AT&T syntax, just because it's the default--no changing compiler options, etc. to get it.

I too cut my teeth on Intel-syntax x86 ASM (on DOS, too) and found it more intuitive initially when switching to C/UNIX. But once you learn AT&T it'll look just as easy.

I wouldn't give it that much thought---it's easy to learn AT&T once you know Intel, and vice-versa. The actual language is much harder to get in your head than the syntax. So by all means just focus on one and then learn the other when it comes up.

Jacob B
  • 1,929
  • 12
  • 11
  • 16
    What? Because GCC uses at&t by default is no reason to learn at&t syntax. Especially when you can just switch it to the more intuitive Intel syntax. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Nov 21 '09 at 21:34
  • 7
    @longpoke Learning intel syntax just because everyone is calling it " more intuitive" is not much of a better reason. Actually it's no reason at all. – Hawken Mar 25 '12 at 14:16
  • 1
    You are both correct, for the same reasons that both Verilog and VHDL have stuck around. – bug Sep 07 '12 at 01:46
  • @Hawken: True. The real reason to learn Intel syntax is that it's what Intel's and AMD's manuals use. There are no ISA reference manuals using AT&T syntax as detailed as the vendor manuals, e.g. https://www.felixcloutier.com/x86/cmppd (extracted from Intel's PDFs). Also performance info like https://uops.info/ and https://agner.org/optimize/. I think I read that some Unix vendor made an AT&T ISA reference at some point, but it's certainly outdated by now and won't cover AVX instructions. 100% agreed with this answer: same machine code, different syntax for expressing it, no biggie. – Peter Cordes Oct 03 '20 at 01:57
20

It's a sign of professionalism that you are willing to adjust to whatever is in use. There is no real advantage to one or the other. The intel syntax is common in the Microsoft world, AT&T is the standard in Linux/Unix. Since there's no advantage to either one, people tend to imprint on whatever they saw first. That said, a professional programmer raises above things like that. Use whatever they use at work, or in the domain that you're working in.

phorgan1
  • 1,494
  • 16
  • 15
  • 5
    How about being a "professional" user of the tools, and knowing how to change them to make you more productive? +1 for Intel syntax. – Jonathon Reinhart Jun 24 '11 at 17:40
  • 5
    Well, although I favour Intel syntax too, he has a point -- consider maintenance of existing AT&T code, for example. There's definitely no harm in knowing your way around both. – Elliott Aug 23 '12 at 21:33
  • 7
    While I would also advocate learning both, I'll play Devil's Advocate and suggest that you could simply script vim into auto-converting *.s files to the syntax of your choice. – bug Sep 07 '12 at 01:50
  • 2
    since intel syntax is easier to read, intel syntax has an advantage. "lea eax, [eax*4+8]" has much better objective readability than "leal 8(,%eax,4), %eax" – Lucio M. Tato Jan 19 '15 at 09:16
  • 2
    @bug Heh, you misspelled emacs ;D – GDP2 Sep 18 '17 at 18:26
13

Intel syntax covers everything (assuming the assembler/disassembler is up to date with the latest junk Intel added to their instruction set). I'm sure at&t is the same.

at&t                             intel
movl -4(%ebp, %edx, 4), %eax     mov eax, [ebp-4+edx*4]
movl -4(%ebp), %eax              mov eax, [ebp-4]
movl (%ecx), %edx                mov edx, [ecx]
leal 8(,%eax,4), %eax            lea eax, [eax*4+8]
leal (%eax,%eax,2), %eax         lea eax, [eax*2+eax]

...and it gets more complicated with more complex instructions

'nuff said.

3

My first assembly language was MIPS, which I've noticed is very similar to the ATT syntax. So I prefer the ATT syntax, but it doesn't really matter as long as you can read it.

gsk
  • 518
  • 5
  • 11
  • 3
    MIPS assembly is only similar to AT&T syntax in the load/store instructon's address format. But MIPS has only 1 simple addressing mode for load/store while Intel has much more, which makes this more complex. Consider `lea -0x30(%rcx,%rax,8),%eax` and `lea eax,[rcx+rax*8-0x30]` jørgensen posted above. And unlike AT&T, MIPS still use the destination-first format like all others. Besides, MIPS number does not need to be prefixed by $, and register names in MIPS is short, so it's not very uncomfortable to have % all the way like AT&T – phuclv Sep 19 '13 at 05:38