Скомпилировать вывод сборки, сгенерированный VC++?

У меня есть простая программа hello world C и я скомпилирую ее с /FA. Как следствие, компилятор также генерирует соответствующий листинг сборки. Теперь я хочу использовать masm/link для сборки исполняемого файла из сгенерированного списка.asm.

Следующая командная строка выдает 3 ошибки компоновщика:

\masm32\bin\ml /I"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include" /c /coff asm_test.asm
\masm32\bin\link /SUBSYSTEM:CONSOLE /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib" asm_test.obj

показывая, что функции времени выполнения C не были связаны с объектными файлами, созданными ранее:

asm_test.obj: ошибка LNK2001: неразрешенный внешний символ @__security_check_cookie@4 asm_test.obj: ошибка LNK2001: неразрешенный внешний символ _printf LINK: ошибка LNK2001: неразрешенный внешний символ _wmainCRTStartup asm_test.exe: фатальная ошибка LNK1120: 3 не разрешено

Вот сгенерированный листинг сборки

; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 

    TITLE   c:\asm_test\asm_test\asm_test.cpp
    .686P
    .XMM
    include listing.inc
    .model  flat

INCLUDELIB OLDNAMES

PUBLIC  ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@   ; `string'
EXTRN   @__security_check_cookie@4:PROC
EXTRN   _printf:PROC
;   COMDAT ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@
CONST   SEGMENT
??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ DB 'hello world!', 0aH, 00H ; `string'
CONST   ENDS
PUBLIC  _wmain
; Function compile flags: /Ogtpy
;   COMDAT _wmain
_TEXT   SEGMENT
_argc$ = 8                      ; size = 4
_argv$ = 12                     ; size = 4
_wmain  PROC                        ; COMDAT
; File c:\users\octon\desktop\asm_test\asm_test\asm_test.cpp
; Line 21
    push    OFFSET ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@
    call    _printf
    add esp, 4
; Line 22
    xor eax, eax
; Line 23
    ret 0
_wmain  ENDP
_TEXT   ENDS
END

Я использую последнюю версию masm32 (6.14.8444).

Обновление:

Как предложил Cogwheel, я включил INCLUDELIB msvcrt.lib в источнике asm. Программа компилируется и создается исполняемый файл, но компоновщик генерирует предупреждение:

msvcrt.lib (crtmanifestrtm.obj): предупреждение LNK4044: нераспознанная опция "manifestdependency:type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3ebebeb1ba игнорируются

Когда я запускаю исполняемый файл, среда выполнения C генерирует следующую ошибку:

Ошибка времени выполнения: R6034 Приложение попыталось загрузить библиотеку времени выполнения C неправильно

3 ответа

Я сделал это недавно. Оказывается, вы все еще можете делать это в 32-битном режиме в MSVC2012, но я думаю, что 64-битный режим безнадежен.

Для 32-битного режима вот что вы делаете.

Создайте пустой проект и исходный файл Source.cpp

 #include <stdio.h>
 int main() {
     printf("hello world\n");
     return 0;
 }
  1. Щелкните правой кнопкой мыши на вашем проекте и выберите "Build Customization" и
    выберите masm, как описано здесь http://www.masm32.com/board/index.php?topic=9231.0
  2. Под C++/OutputFiles выберите Сборка Выход / FA
  3. Comipile в 32-битном режиме Release mode
  4. Загрузите файл Source.asm в MSVC, чтобы вы могли просмотреть его. Это пока не сработает. Несколько изменений необходимы.
  5. В C++ / Оптимизация отключить Оптимизацию всей программы (удаляет /GL). Это добавляет строку INCLUDELIB MSVCRT
  6. В Linker/Advanced установите для последней опции "Image Has Safe Exception Обработчики" значение No (/SAFESEH:NO)
  7. Теперь у вас должен быть файл Source.asm, который будет делать то же самое, что и файл Source.cpp. Скопируйте Source.cpp из каталога Release в тот же каталог, что и Source.cpp (чтобы он не удалялся при сборке / очистке).
  8. Добавьте Source.asm (как существующий файл) к исходным файлам и удалите Source.cpp из сборки.
  9. Перестройте, и вы должны увидеть "Hello World" без необходимости менять какие-либо сборочные линии вручную.

Я использовал это для более сложных функций. Я обычно делаю это на отдельном модуле и использую extern "C" на имя функции, чтобы удалить искажение имени C++.

Вот лучшая ссылка для сборки с CRT 9

http://www.masm32.com/board/index.php?topic=9231.0

Удалите перечисление.inc Удалите ссылку на security_check_cookie, добавьте INCLUDELIB MSVCRT ... и Роберт!

Также вы можете добавить: EXTERN _getchar:PROC и непосредственно перед ret: call _getchar Это будет ждать нажатия клавиши до закрытия программы.

Honkjonk.

Другие вопросы по тегам