6

The AT&T assembly syntax, often called the GAS syntax, keeps surprising me. For example, its parameter order:

mov $100,%eax /* Destination after source */

This just seems so counter-intuitive! Nearly all programming languages (and the good old mathematical notation) go the other way around: destination before source, like this:

int a = 100;   /* Destination before source (C-style) */
a := 100       // Destination before source (Pascal-style)
mov eax,100    ;  Destination before source (Intel assembly syntax)

There are other points, for example, sigils... The %-s before every register and the $ before every constant literal (except for those used as the fourth operand in the very strange-looking effective addressing syntax) mightily clutter up the code, when it would have been trivial to avoid them. What is, or was, their advantage?

  • 5
    Relevant. – Neil Apr 20 '15 at 8:38
  • Also sigils greatly reduce parsing complexity because the first character tells exactly what the word is and can be fed into a switch. – ratchet freak Apr 20 '15 at 8:40
  • @ratchetfreak: isn't the same thing possible without them sigils? – Mints97 Apr 20 '15 at 8:41
  • 1
    it's possible but in ye olde days of RAM counted in kilo bytes and clock speeds not that much more simplifying the parser trumps simplifying it for the user. – ratchet freak Apr 20 '15 at 8:50
  • 1
    ATT code is the output of a compiler which was the input to the assembler. It was not intended to be written by programmers directly. Intel assembly is intended for programmers to use directly. – Rob Apr 20 '15 at 13:25
4

I do not know what the deal is with sigils, other than perhaps to scare the uninitiated and to annoy those wise enough to know that they could have very easily been missing. Hopefully, another answerer will have more insight on this. (As ratchet freak mentioned in the comments, it was probably done this way in order to simplify the parser, which perhaps made sense back in those days when computing resources were meager.)

Now, as far as operand order is concerned, there are arguments that can be made for it and against it, although the arguments against it win.

It can be argued that GAS syntax is slightly more consistent than, say, Intel syntax, because when thinking of "moving" stuff, something gets moved from one place to another. When reading the code out loud, it makes sense to say "move this value to that register", but it does not make sense to say "move this register from that value".

By contrast, other assembly languages (Zilog, etc.) call these instructions "ld", which stands for "load", where it makes sense to have destination before source, because something is being loaded with a value. This has the additional benefit of following the standard operand order of mathematics, but it can be argued that this is not necessary, because assembly language programming is not mathematics, and there is no need to pretend that it is. (Similar things should look similar, and different things should look different.)

Of course, the argument for GAS syntax is lost if you consider that "move" is the wrong choice of verb in the first place, because the source operand does not lose its contents as a result of the "mov" operation: the bits do not really get moved, they are copied.

And then things get complicated even more by the fact that the Intel x86 instruction set includes instructions such as "lea" (load effective address) which go with the "load" verb instead of the "move" verb, in which case the GAS operand order is just plain wrong from whichever way you look at it.

Bottom line: it is just a matter of convention, so whoever builds the CPU gets to pick their preferred convention, and then whoever writes an assembler which is not required to be compatible with preexisting assemblers may, if they so please, come up with their own convention. The first GAS assembler was probably written for some architecture in which the convention was source-operand-first, and then in subsequent ports of the assembler to other architectures the authors decided that having to change the instruction set and the register set was enough of a burden already, so they probably thought that it would be cool to at least stick with the same operand order.

  • +1 for bringing up Zilog's assembly, never heard about this style before. Also, the linguistical part on mov looks interesting =) – Mints97 Apr 20 '15 at 9:03
  • "Load" could work both ways: "Load 123 into register A" or "load register A with 123." The sigils call out immediate values ($) and registers (%), making it easier for the assembler to distinguish them from other symbols. This is particularly important in data movement instructions which on some processors have a very large number of variants. – Blrfl Apr 20 '15 at 11:55
  • @Blrfl: If a label is allowed to have the same name as a register (e.g. D0) and the same mnemonic can be used to act upon the contents of that register, the address associated with the label, or the contents of memory at that address, there needs to be a syntactic difference between them. I like regName, #symbol, and [symbol] as notation, but using a prefix before the register name is also perfectly reasonable. – supercat Oct 10 '16 at 16:39
2

The simple answer is thats the order the binary instructions on most processors are laid out.

Back when men were men and sheep were scared assembly programers spent a lot of time looking at raw binary code (and sometimes trying to infer what instruction was hanging from the on/off lights in the control panel). It was just easier if the assembly code followed the instruction,target,source order of the machine code.

  • 6
    But at&t follows instruction,source,target, not the other way around... – Mints97 Apr 20 '15 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.