Как изменить имя точки входа в простой программе сборки?

#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 как синоним / псевдоним, который на самом деле виден для ссылки.)