Limitations of Intel Assembly Syntax Compared to AT&T [closed]
Asked Answered
I

7

100

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.

Incogitant answered 9/6, 2009 at 21:28 Comment(0)
Y
92

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.

Yangyangtze answered 9/6, 2009 at 21:32 Comment(19)
as well, echo set dis intel >> ~/.gdbinitIncogitant
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?Chyou
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.Malleus
I'd like to see what Hawken has to say about this example.Wicker
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.Hamster
@Chyou 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).Hipped
@Ken I personally like the way AT&T's register % looks; call me weird ;). The $ do get occasionally tedious, I'll admit.Chyou
@Chyou 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).Hipped
@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].Chyou
@Chyou Ah, I thought so but it seemed not consistent. Thanks!Hipped
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' assignmentChevrotain
@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 ;)Pogonia
@Pogonia 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.Chevrotain
... 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.Chevrotain
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 + dChevrotain
@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.Pogonia
@Pogonia 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 senseChevrotain
@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."Pogonia
@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).Pogonia
L
50

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.

Labia answered 9/6, 2009 at 21:36 Comment(7)
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.Wicker
If you are going to state it in bold at least provide some evidence as to why intel is so much better.Chyou
@Chyou Haters gonna hateEsme
@Chyou 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!Gerent
How about Intel syntax for ARM?Caftan
@L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ What is reverse SIB notation?Jurisprudence
@PetrSkocik I guess SIB is referring to Scale, Index, Base and it's reverse SIB because in AT&T syntax you have to specify it as disp(base,index,scale) (which in Intel syntax is just [base+index*scale+disp].Granddad
E
36

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.

Esme answered 31/3, 2012 at 18:22 Comment(15)
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.Wicker
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.Wicker
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...Wicker
@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.Esme
@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).Esme
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.Wicker
Just try objdump -M intel for a start.Esme
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.Wicker
+1 for a witty comeback and making a good point. I laughed.Hibbs
So are you saying -4(ebp,edx,4) thing is better than [4*edx+ebp-4]? I find the latter more intuitive.Gantline
@Gantline 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 ;-)Esme
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..Unspoiled
Self-contradiction is not convincing, impersonally.Ballarat
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.Pneumodynamics
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.Pneumodynamics
N
27

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.

Nomenclator answered 9/6, 2009 at 21:37 Comment(4)
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.Wicker
@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.Chyou
You are both correct, for the same reasons that both Verilog and VHDL have stuck around.Hamster
@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. felixcloutier.com/x86/cmppd (extracted from Intel's PDFs). Also performance info like uops.info and 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.Pneumodynamics
P
22

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.

Pectinate answered 21/6, 2011 at 6:25 Comment(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.Hydrodynamics
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.Gerent
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.Hamster
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"Karaganda
@Hamster Heh, you misspelled emacs ;DPogonia
C
14

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.

Canuck answered 31/3, 2012 at 0:24 Comment(4)
No, not enough said.Esme
The poster already stated that they prefer intel syntax; good for them; so who are you trying to convince?Chyou
@Chyou it's not just the poster who's going to read the answers.Lest
I like how he mentions example with dword length. Please write a memory operand on single byte or short.Tralee
I
4

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.

Incurable answered 7/11, 2010 at 19:14 Comment(1)
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&TChevrotain

© 2022 - 2024 — McMap. All rights reserved.