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)


arrow_upward
4
arrow_downward

  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