x86 масм привет мир

Я пытаюсь скомпилировать hello world в Windows с помощью ML и LINK, которые поставляются с VS 2010.

.MODEL FLAT
.STACK 4096
.data
msg db "Hello World!",0
.code
INCLUDELIB MSVCRT
EXTRN printf:NEAR
EXTRN exit:NEAR
PUBLIC _main
_main PROC
mov eax, offset msg
push eax
call printf
mov eax,0
push eax
call exit
_main ENDP
END _main

Я продолжаю получать ошибки компоновщика, говорящие, что printf и exit являются неразрешенными внешними символами. У меня есть пара вопросов.

  1. Какие параметры командной строки следует использовать с ML и LINK для компиляции и устранения сообщений об ошибках.
  2. Есть ли другой способ отобразить вывод текста на экран с помощью ассемблерного кода, а не вызывать функции времени выполнения c, такие как printf?

person alphadev    schedule 10.10.2010    source источник


Ответы (1)


  1. Вам нужно использовать подчеркнутые имена для функций C, поскольку именно так компилятор выдает их на уровне сборки.
  2. Вы должны очистить стек после вызова printf и других функций CRT, так как они используют соглашение о вызовах cdecl (очистка стека вызывающей стороны). Строго говоря, вы должны сделать это и после _exit, но это менее важно, так как он никогда не возвращается.
  3. Чтобы использовать функции 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) для дескриптора файла). См. несколько примеров здесь.

person Igor Skochinsky    schedule 14.10.2010
comment
Привет Игорь, Не могли бы вы сказать мне, как связать с __mtinit, __ioinit... Я пробовал cl /MT final.obj /link kernel32.lib msvcrt.lib, но это не работает... - person lllllllllllll; 19.02.2014