#foofor an immediate operand in -11 assemblers; the Unix guys apparently preferred
$foo, which to my eyes lacks any mnemonic significance. Similarly
*. Does anyone know the rationale or is this just personal taste?
The Unix Assembly Reference Manual by Dennis M. Ritchie, at §8.1 notes that:
The syntax of the address forms is identical to that in DEC assemblers, except that ‘‘*’’ has been substituted for ‘‘@’’ and ‘‘$’’ for ‘‘#’’; the UNIX typing conventions make ‘‘@’’ and ‘‘#’’ rather inconvenient.
In a SO answer, and in this comment, fuz notes that this is because
@ are used as control
characters by the early TTY drivers in Unix. This is indeed so, with
the kill-line function, and
# erases the last character¹.
This can be seen in the Unix History Repository at u7.s:
jsr r0,cesc; 100 / test for @ (kill line) br canon / character was @ so start over jsr r0,cesc; 43 / test for # (erase last char. typed) br 1b / character was #, go back
(100 is the octal code for @, and 43 the octal code for #).
One would expect Unix would have adopted other characters for erase-kill
processing, since the chosen ones clash with characters used by the assembler.
But recall that Unix originated in a PDP-7. Erase-kill processing with
was already in PDP-7 Unix, Dennis M. Ritchie in The Evolution of the Unix
Time-sharing System notes that:
Only a few programs (notably the shell and the editor) bothered to implement erase-kill processing.
which I think correspond to this code in ed1.s:
esc: 0 sna jmp i esc jms putsc; tal sad o12 jmp 2f sad o100 jmp 1f sad o43 skp jmp i esc -1 tad tal dac tal and o17777 sad linpm1 jmp 1f jmp i esc 1: lac linep dac tal jmp i esc 2: lac tal sma cla jmp 1f jms putsc; tal
rline: 0 law ibuf-1 dac 8 1: cla sys read; char; 1 lac char lrss 9 sad o100 jmp rline+1 sad o43 jmp 2f dac 8 i sad o12 jmp rline i jmp 1b 2: law ibuf-1 sad 8 jmp 1b -1 tad 8 dac 8 jmp 1b
Mark Plotnick notes in a comment that Unix inherited the erase and kill characters from Multics. Following that lead, we can arrive at "Remote Terminal Character Stream Processing in Multics" (1970), which explains that:
It should be possible to determine from the printed page, without ambiguity, both what went into the computer pro- gram and what the program tried to print out.
which is the rationale for using printing characters for erase and kill (recall that back then users typed at teletypes, the typewriter-like ones).
It also mentions a special editor on the 7094 Compatible Time-Sharing System as a prior implementation of the things talked about in the paper, which may or may not refer also to erase and kill. Anyway, that special editor is probably TYPSET (of the TYPSET/RUNOFF workflow²), and it indeed used
@ as defaults for erase and kill characters, as mentioned in TYPSET and RUNOFF, Memorandum editor and type-out commands (1964). While Project MAC Technical Report MAC-TR-16 mentions erase and kill processing in CTSS (figure in page 23, first paragraph in page 24), that report is from a later date, and doesn't mention which characters were used.
A little more digging leads us to the CTSS Programmer's Guide, which in its 1963 edition uses
? for delete-character and delete-message while the 1966 edition already gives
@. "Introduction to CTSS Usage" (July 1967) gives both
# for deleting the previous character, and
@ for deleting everything typed since the previous carriage return. So TYPSET may well be the first program to use
@, from where it spread to CTSS, Multics, and eventually Unix.
¹ Incidentally, in early Unix as, as documented in man11 from the 1st edition of the Unix Programmer's Manual, there is another substitution:
Character changes are: for use @ * # $ ; /
So, comments are marked by a slash.
² A nice history of RUNOFF/roff/... can be found at https://manpages.bsd.lv/history.html