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?
