- Вам необходимо использовать подчеркнутые имена для функций C, поскольку компилятор выводит их на уровне сборки.
- Вы должны очистить стек после вызова printf и других функций CRT, так как они используютСоглашение о вызовах cdecl (очистка стека вызывающих).Строго говоря, вы должны делать это и после _exit, но это менее важно, поскольку оно никогда не возвращается.
- Чтобы использовать функции CRT, вы должны инициализировать CRT.Вы можете проверить, как это делается в файле
VC\crt\src\crt0.c
Вот минимальный файл, который работал для меня (я использовал статическую библиотеку, потому что у меня есть VS2008 и не хотел возиться с манифестами, чтобы сделать эторабота с DLL).
.386
.MODEL FLAT
.STACK 4096
.data
msg db "Hello World!",0
.code
INCLUDELIB LIBCMT
EXTRN _printf:NEAR
EXTRN _exit:NEAR
EXTRN __heap_init:NEAR
EXTRN __mtinit:NEAR
EXTRN __ioinit:NEAR
PUBLIC _main
_main PROC
push 1
call __heap_init
add esp, 4
push 1
call __mtinit
add esp, 4
call __ioinit
mov eax, offset msg
push eax
call _printf
pop ecx
mov eax,0
push eax
call _exit
_main ENDP
END _main
Для MSVCRT инициализация отличается, например, вам нужно вызвать set_app_type
Чтобы не полагаться на CRT, вы должны использовать API-интерфейсы ОС.В случае Win32 это будут функции Win32, такие как WriteFile (с GetStdHandle (STD_OUTPUT_HANDLE) для дескриптора файла).Смотрите примеры здесь .