Apparently some of the earlier TI graphing calculators (TI-83) were Z80 based before they switched to the 68000 series, so there seem to be a whole slew of assemblers out there. There's entire *fansites* for the architecture.
http://www.z80.info/
GPL'd assembler/disassembler.
http://wwwhomes.uni-bielefeld.de/achim/z80-asm.html
some nomenclature:
1) An assembler just translates assembly instructions into opcodes, handles relative addressing (i.e. jumps), and usually does macros.
2) An assembler isn't a compiler, compilers tend to do a *lot* more than assemblers.
3) Assemblers typically output binary files, and a secondary output is typically an annoted source file. I usually don't use linkers when dealing with assembly, but that's usually doable too (multiple .asm files -> assembled into multiple object files -> linked into a single binary file)
4) If you tell the assembler to allocate some memory and dump the ascii characters 'H', 'e', 'l', 'l', 'o', it'll happily put the ascii characters into the object file with the other opcodes. (unless you *really* *really* want to do unicode, utf, ebcdic or some other funky encoding...)
James