1

Traditionally, assemblers use # to indicate an immediate operand. This is true at least since DEC PDP-11 assemblers; possibly longer. Here is an example from Kermit-11 (https://gitlab.com/Rhialto/kermit11/blob/master/k11cvt.mac)

10$:    tst     r1                      ; current state is zero?
        beq     20$                     ; yes, exit then
        clr     r3                      ; get the next ch please
        bisb    (r2)+   ,r3             ; simple
        bic     #^c<177>,r3             ; ensure in range 0..127
        dec     r1                      ; use previous state to get the
        mul     #10     ,r1             ; index into the state table  line
        movb    chtype(r3),r0           ; /BBS/                       column
        add     r0      ,r1             ; add in the character class  line+col
        movb    ptable(r1),r1           ; and get the new state of system
        beq     20$                     ; all done if new state is zero
        bmi     30$                     ; error exit if < 0
        clr     r0                      ; now mask off the action index from
        div     #10.    ,r0             ; the new state
        asl     r0                      ; word indexing to action routine
        jsr     pc      ,@paction(r0)   ; simple
        br      10$                     ; next please

However, the GNU assembler seems to use $:

main:
.LFB0:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        movq    %rsi, -16(%rbp)
        movl    $0, %eax
        popq    %rbp
        ret

even though the $ is typically used to indicate hexadecimal constants. This is true at least since 6502 and 68000 assemblers. Random examples from http://6502.org/source/games/uchess/uchess.htm:

; 6551 I/O Port Addresses
;
ACIADat =   $7F70
ACIASta =   $7F71
ACIACmd =   $7F72
ACIACtl =   $7F73

Traditionally (and much to my personal annoyance, because I'm used to the other way) 8x86 instructions have the destination operand first and the source second. But the GNU assembler for x86 / x86_64 code swaps the operand order. See the movl $0, %eax which makes no sense otherwise.

Additionally (see * in front of instruction operand, GNU assembly, AMD64 for an example), the GNU assembler uses * instead of @ to indicate a second level of indirection (compare the PDP-11 jsr pc,@paction(r0))

Why is the GNU assembler going against all these standards?

  • 1
    Because there is no standard – Michael Petch Nov 03 '18 at 12:29
  • [Questions about AT&T x86 Syntax design](https://stackoverflow.com/q/4193827) includes the question about `$` for immediates. Also related: [What was the original reason for the design of AT&T assembly syntax?](https://stackoverflow.com/q/42244028). – Peter Cordes Nov 03 '18 at 12:37
  • If you don't like AT&T syntax, don't use it. Most tools that default to AT&T will use GAS `.intel_syntax noprefix` MASM-like syntax if you run them with `-Mintel`. (If you're working on asm source files, though, like in the glibc source code, you do sometimes need to use AT&T. It's rare for hand-written `.S` files, and very rare for inline asm, to use Intel syntax.) For compiler output, if you build with optimization enabled, you don't have to wade through crappy un-optimized code in either syntax, just `xor eax,eax` / `ret`. [Remove "noise" from GCC/clang assembly output?](/q/38552116) – Peter Cordes Nov 03 '18 at 12:40
  • I wrote an answer to pretty much all your questions about a year ago. See the duplicate for details. – fuz Nov 03 '18 at 13:04
  • 1
    @fuz and Peter Cordes: ah thanks! Those links are illuminating. – Rhialto supports Monica Nov 03 '18 at 14:20
  • @Rhialto My pleasure. Let me know if any questions remain so I can address them. – fuz Nov 03 '18 at 14:28

0 Answers0