Kleine Korrektur: das Voranstellen von Unterstrichen ist heutzutage
weniger üblich. In der Historie rührte das daher, dass der
PDP-11-Assembler die Namen der Register (r0 bis r6 alias sp, pc) als
ganz normale Namen geführt hat und sie daher nicht von externen
Symbolen trennen konnte. Da nun diese Namen aber auch gültige
C-Identifier sind, hat der C-Compiler jedem Identifier einen
Unterstrich vorangestellt, sodass nie ein Konflikt mit einem
Registernamen entstehen konnte.
Heutzutage wird der Konflikt typischerweise anders aufgelöst. Der
GNU-Assembler für i386 benutzt bspw. ein % als Symbol für
Registernamen (%eax usw.), damit kann man das globale Symbol eax immer
vom Register %eax unterscheiden.
Beim AVR ist anhand des Opcodes bereits eindeutig ermittelbar, ob der
Operand ein Register sein kann oder nicht, der GNU-Assembler
akzeptiert dabei auch reine Zahlen für einen Registernamen (also r0
und 0 sind dasselbe).
Extern definierte globale Symbole müssen nicht zwingend deklariert
werden im Assemblercode (unbekannte Namen werden beim Auftreten im
Assembler immer erstmal als "external undefined" behandelt), aber es
ist guter Stil, sie zu deklarieren:
.extern foo
Wenn man im Assemblerprogram ein globales Symbol definieren will, tut
man das mit .global:
.global foo
foo: ...
Damit kann es dann von C aus zugegriffen werden -- die typmäßig dazu
passende C-Deklaration muss man sich natürlich selbst schreiben.