This can be done even simpler:
global _start
_start:
jmp next
string:
db `Hello World!\n`
len: equ $ - string
next:
mov ecx, string
mov edx, len
mov ebx, 1
mov eax, 4
int 80h
mov ebx, 0
mov eax, 1
int 80h
For NASM, it can also be put into a macro, for example printing to video memory at 0xb8000: %macro print 1
mov ecx, %%loop_start - %%strdata
mov eax, 0x0700
jmp %%loop_start
%%strdata: db %1
%%loop_start:
mov al, [%%strdata + ecx - 1]
mov [0xb8000 + ecx * 2 - 2], ax
loop %%loop_start
%endmacro