This is something the late Chuck Crayne (RIP, Chuck!) left for us to study. I may have meddled with it a little, but it's mostly Chuck's code. I can confirm that the elf32 version works... Feedback on other formats?
Post it in code tags, or attach it? Why not both?
global _start
section .data
string1 db "Hello World!",10,0
section .text
_start:
%ifidn __OUTPUT_FORMAT__, elf64
; calculate the length of string
mov rdi, string1
mov rcx, -1
xor al,al
cld
repnz scasb
; place the length of the string in RDX
mov rdx, -2
sub rdx, rcx
; print the string using write() system call
mov rsi, string1
push 0x1
pop rax
mov rdi,rax
syscall
; exit from the application here
xor rdi,rdi
push 0x3c
pop rax
syscall
%elifidn __OUTPUT_FORMAT__, elf32
mov ecx, string1
; calculate the length of string
or edx, byte -1
.getlen:
cmp byte [ecx + edx + 1], 1
inc edx
jnc .getlen
; place the length of the string in EDX
nop
; print the string using write() system call
push byte 1
pop ebx
push byte 4
pop eax
int 80h
; exit from the application here
xor ebx, ebx
push byte 1
pop eax
int 80h
%elifidn __OUTPUT_FORMAT__, macho
; calculate the length of string
or eax, byte -1
getlen2:
cmp byte [string1 + eax + 1], 1
inc eax
jnc getlen2
; print the string using write() system call
push eax
push string1
push 1
mov eax, 4 ; __NR_write
call sys_call
; exit from the application here
push 0
mov eax, 1
call sys_call
sys_call:
int 80h
ret
%else
%error "Output Format (-f) must be elf32, elf64, or macho!"
%endif
Best,
Frank