Скомпилировать вывод сборки, сгенерированный VC ++? - PullRequest
5 голосов
/ 12 мая 2010

У меня есть простая программа 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 ССЫЛКА: ошибка 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' версия = '9.0.21022.8' processorArchitecture = 'x86' publicKeyToken = '1fbe188 «"; проигнорировано

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

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

Ответы [ 3 ]

0 голосов
/ 21 апреля 2013

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

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

Honkjonk.

0 голосов
/ 18 января 2014

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

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

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

 #include <stdio.h>
 int main() {
     printf("hello world\n");
     return 0;
 }
  1. Щелкните правой кнопкой мыши на вашем проекте и выберите «Настройка сборки» и
    выберите маску, как описано здесь http://www.masm32.com/board/index.php?topic=9231.0
  2. В C ++ / OutputFiles выберите Сборка Output / FA
  3. Comipile в 32-битном режиме. Режим выпуска
  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 ++.

0 голосов
/ 08 января 2012

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

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

...