Скомпилировать сборку, сгенерированную VС++?

У меня есть простая программа 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-runtime не были связаны с ранее созданными объектными файлами:

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  [email protected][email protected]@[email protected]   ; `string'
EXTRN   @[email protected]:PROC
EXTRN   _printf:PROC
;   COMDAT [email protected][email protected]@[email protected]
CONST   SEGMENT
[email protected][email protected]@[email protected] 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 [email protected][email protected]@[email protected]
    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 = ' 1fc8b3b9a1e18e3b"; игнорируется

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

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

Ответ 2

Удалить список .inc Удалить ссылку security_check_cookie добавить INCLUDELIB MSVCRT ... et Robert est ton oncle!

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

Honkjonk.

Ответ 3

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

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

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

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

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