In the interest of completeness, here is how to do it without C.
Using DOS interrupts
AH = 02h -WRITE CHARACTER TO STANDARD OUTPUT
Writes character in DL. I haven't tested this myself. in NASM syntax something like
mov ah, 02h
int 21h
x86-32 Linux write syscall
write requires the address of your string. The easiest way I know of is to push your character on the stack.
push $0x21 # '!'
mov $4, %eax # sys_write call number
mov $1, %ebx # write to stdout (fd=1)
mov %esp, %ecx # use char on stack
mov $1, %edx # write 1 char
int $0x80
add $4, %esp # restore sp
Info on register order
x86-64 Linux write syscall
Similar to above, but the call number is now 1, syscall instead of int $0x80, and the calling convention registers are different.
push $0x21 # '!'
mov $1, %rax # sys_write call number
mov $1, %rdi # write to stdout (fd=1)
mov %rsp, %rsi # use char on stack
mov $1, %rdx # write 1 char
syscall
add $8, %rsp # restore sp