sunshine33, I am not familiar with SASM. But it looks like you have many duplicates and mismatch in there.
Issues;
1. ld requires the entry point "start", "_start" or "Start". This is ld (linker's) requirement. You have 2 different entry points, CMAIN and go ... which are duplicates and non-ld friendly anyway. My guess is that SASM puts CMAIN there for you by default?
2. "io.inc" is not exposed. I don't have the slightest clues what it contains and what it does.
3. I don't know what "libkernel.a" is. Looks like SASM is pre-configuring it for you or SASM has its own set of kernel library?
My suggestion is that you avoid SASM at this moment because it has many configuration defaults that may be conflicting with others such as the linkers.
I modified your code so that it works with GCC as the linker. GCC is including the "kernel32.dll" by default. This runs from the console. There are small modifications as well;
;Compile: nasm -f win this.asm
;Link: gcc -m32 this.obj -s -o this.exe
global _WinMain@16
extern _ExitProcess@4
extern _GetStdHandle@4
extern _WriteConsoleA@20
extern _ReadConsoleA@20
section .data
msg: db 'Hello, World',0
handle: dd 0
read_handle dd 0
written dd 0 ;This should not be a byte.
section .text
_WinMain@16:
; handle = GetStdHandle(-11)
push dword -11
call _GetStdHandle@4
mov [handle], eax
push dword -10 ; stdin
call _GetStdHandle@4
mov [read_handle], eax
; WriteConsole(handle, &msg[0], 13, &written, 0)
push dword 0
push written
push dword 12
push msg
push dword [handle]
call _WriteConsoleA@20
push eax
mov eax, esp ; buffer for char?
push 0
push written ; reuse this?
push dword 1 ; characters to read?
push eax
push dword [read_handle]
call _ReadConsoleA@20
pop eax ; character read in al?
; ExitProcess(0)
push dword 0
call _ExitProcess@4
p/s You probably need to upgrade your GCC from mingw to TDM-GCC and set the correct PATH to it.