#windows #visual-studio #assembly #masm
Вопрос:
Имея такую простую программу сборки Win32
.386 .model flat, c option casemap :none ;includelib C:UsersDarekDevVCliblibcmt.lib ;includelib C:UsersDarekDevVCliblegacy_stdio_definitions.lib EXTERN printf :PROC ; declare printf .data HelloWorld db "Hello j World!:-)", 0 .code main PROC push offset HelloWorld call printf add esp, 4 ret main ENDP END
Я хотел бы изменить имя точки входа со стандартного main
на my_start, поэтому я изменил имя основной функции на my_start
... my_start PROC ... my_start ENDP ...
а затем связаны, как показано ниже
link /ENTRY:my_start /SUBSYSTEM:CONSOLE HelloWorld.obj libcmt.lib
но получение ошибки компоновщика:
неопределенный внешний символ _main, вызываемый в _mainCRTStartup. Почему компоновщик использует параметр ВВОДА? Что я делаю неправильно и что нужно сделать, чтобы это сработало?
P.S.
Я использую ml
и link
предоставленный с моим MSVC 2019
Комментарии:
1. Фактическая точка входа находится в библиотеке C, которая затем вызывает вашу
main
.2. @Jester Извините, но не могли бы Вы объяснить мне подробнее?
3. Попробуйте использовать «msvcrt.lib» вместо «libcmt.lib». Я попробовал ваш код, добавив следующую строку вверху:
includelib "Program Files (x86)Microsoft Visual Studio 10.0VClibmsvcrt.lib"
(нет необходимости добавлять какие-либо дополнительные файлы в команду компоновщика), и это сработало.4. @AdrianMole. Хорошо, что переход с
libcmt
наmsvcrt
сделал работу, НО не могли бы вы быть таким милым и объяснить мне, почему решение сlibcmt
ЭТИМ НЕ работает? Разве опция »libcmt
Принять точку входа» не работает?
Ответ №1:
C требует, чтобы была вызвана ваша основная программа main
. Это ограничение, налагаемое C, а не самим оборудованием. Я когда-либо использовал только UASM и x86-16, поэтому я не знаком с синтаксисом Win32, но вы могли бы попробовать это:
my_start equ main
(Предполагая, что у Win32 есть equ
директива, которая есть.)
Комментарии:
1. Win32-это целевая платформа, а не ассемблер. В этом случае ассемблером является MASM, но другие ассемблеры (например, NASM или FASM) также могут быть нацелены на объектные файлы Win32 или исполняемые файлы. В NASM
equ
определенно работает только с числами или уже определенными символами, а не с подстановкой текста, как в макросах CPP. В FASM это замена текста. Не уверен насчет МАСМА.2. Справедливо. Я не привык использовать PROC для своих подпрограмм (я только недавно обнаружил, что он существует), поэтому я не совсем знаком с тем, что вы можете и не можете с ним делать.
3. Это не имеет значения для того, что вы можете сделать
equ
в MASM, но ладно.4. Я подумал, может быть, вы могли бы сказать что-то вроде
PROC main
, а затем сделатьmy_start equ main
так, чтобы в вашем коде вы могли использоватьCALL main
илиCALL myStart
взаимозаменяемо.5. О, да, вы, возможно, сможете это сделать (если вы связываете код CRT, который хочет вызвать main, вместо того, чтобы фактически сделать это точкой входа в процесс). Но кода в вопросе
proc my_start
нетproc main
, так что вашequ
-наоборот. (Хотя IDK, если бы это работало наоборот, чтобы определитьmain
как синоним / псевдоним, который на самом деле виден для ссылки.)