I've been doing a lot of x64-related work lately and I needed to code some simple programs to use as tests. Here's the latest which you might find useful.
Also with the directives I've used you'll be able to use the relevant pieces directly. I do hope they introduce dp and resp pseudo-instructions like this to make easier pointer-length variables with no checks.
Anyway if you didn't know already Thread Local Storage (TLS) Callback functions are called before the main entry point. The linker will look for the global variable _tls_used.
The contents of the program itself are nothing glamorous. Just simple MessageBoxA examples.
BITS 64
extern __imp_GetCommandLineA
extern __imp_MessageBoxA
%if __BITS__ == 64
%idefine RESP RESQ
%idefine DP DQ
%elif __BITS__ == 32
%idefine RESP RESD
%idefine DP DD
%else
%idefine RESP RESW
%idefine DP DW
%endif
STRUC IMAGE_TLS_DIRECTORY
StartAddressOfRawData: RESP 1
EndAddressOfRawData: RESP 1
AddressOfIndex: RESP 1
AddressOfCallBacks: RESP 1
SizeOfZeroFill: RESD 1
Characteristics: RESD 1
ENDSTRUC
default rel
SECTION .text
global main
global _tls_used
main:
push rdi ;save rdi
sub rsp, 32 ; mandatory top 4 stack elements to be used by APIs
call [__imp_GetCommandLineA]
xor r9, r9
lea r8, [label2]
mov rdx, rax
xor rcx, rcx
call [__imp_MessageBoxA]
add rsp, 32
pop rdi
ret
align 16
tlsfunc:
push rdi
sub rsp, 32
xor r9, r9
lea r8, [msg]
lea rdx, [tlsmsg]
xor rcx, rcx
call [__imp_MessageBoxA]
add rsp, 32
pop rdi
ret
SECTION .data ; data section
global _tls_indexq
msg: db "Hello World!",0 ; the string to print, 10=line feed
tlsmsg: db "I'm the TLS callback function.",0
label2: db "Command line is",0
_tls_index: dp 0
array_tls_index: dp _tls_index, 0
array_tls_func: dp tlsfunc, 0
_tls_used:
ISTRUC IMAGE_TLS_DIRECTORY
IMAGE_TLS_DIRECTORY.StartAddressOfRawData dp 0
IMAGE_TLS_DIRECTORY.EndAddressOfRawData dp 0
IMAGE_TLS_DIRECTORY.AddressOfIndex dp array_tls_index
IMAGE_TLS_DIRECTORY.AddressOfCallBacks dp array_tls_func
IMAGE_TLS_DIRECTORY.SizeOfZeroFill dd 0
IMAGE_TLS_DIRECTORY.Characteristics dd 0
IEND