Скорая Компьютерная Помощь г. Калуга

Полный спектр компьютерных услуг!

Здравствуйте, гость ( Вход | Регистрация )

> Внимание!

  • Вся информация, расположенная в данном и других разделах форума получена из открытых источников (интернет-ресурсы, средства массовой информации, печатные издания и т.п.) и/или добавлена самими пользователями. Администрация форума предоставляет его участникам площадку для общения / размещения файлов / статей и т.п. и не несет ответственности за содержание сообщений, а также за возможное нарушение авторских, смежных и каких-либо иных прав, которое может повлечь за собой информация, содержащаяся в сообщениях.
Ремонт компьютеров в калуге Рекламное место сдается
 
Ответить в эту темуОткрыть новую тему
> [Из песочницы] Assembler вместе с C++ в Visual Studio 2013
Decker
сообщение 10.3.2015, 17:25
Сообщение #1


Администратор
*****

Группа: Главные администраторы
Сообщений: 14349
Регистрация: 12.10.2007
Из: Twilight Zone
Пользователь №: 1




Visual Studio*,
C++*,
Assembler*
Идея этой статьи отнюдь не новая, но, поскольку мне пришлось потратить два дня на разбор всех ошибок компиляции и линковки, а также поиск ответов на свои вопросы, решил, что читатели Хабра заслуживают на экономию времени. Тех, кто желает быстро узнать, как использовать одновременно *.asm и *.cpp файлы в проекте, как вызывать методы C++ из ассемблера и наоборот, прошу пожаловать под кат.




[b]Предисловие[/b]


Началось все с прочтения мной публикации «Ассемблер для Windows используя Visual Studio» (отсюда и почти идентичный код). Там рассмотрено использование Visual Studio 2005, а для 2013-й студии процесс похожий, но есть несколько отличий, которые заставят неподготовленного пользователя долго искать решения всех проблем со сборкой.




[b]Содержание[/b]


  1. TL;DR
  2. Создание проекта
  3. Настройка подсветки синтаксиса
  4. Тонкости вызова методов между С++ и Asm
  5. Приложение



[b]TL;DR[/b]


Для тех, у кого совсем нет времени на прочтение: в конце статьи (в приложении) есть ссылка на готовый шаблон проекта и на аддон для подсветки синтаксиса.




[b]Создание проекта[/b]


Иллюстрированная версияВключаем Visual Studio, выбираем File -> New -> Project...:







Выбираем шаблон Win32 Console Application, кликаем ОК:







Жмем Next:







Ставим галочку напротив Empty project и жмем Finish:







Создаем исходники. Для этого делаем правый клик на Source Files, выбираем Add -> New Item...:







Выбираем C++ File и жмем Add:







Аналогично, создаем *.asm файл (просто меняем расширение в поле Name):







Важно: имена файлов должны быть разными (не учитывая расширение), иначе при создании файлов *.obj возникнет проблема перезаписи одного обьектного файла другим.



Теперь настройки. Делаем правый клик на проекте, выбираем Build Dependencies -> Build Customizations...







Ставим галочку напротив masm и жмем ОК:







Делаем правый клик на файле *.asm, выбираем Properties...:







В поле Item Type выбираем Microsoft Macro Assembler и жмем ОК:







Выбираем Project -> Properties...:







Выбираем Configuration Properties -> Microsoft Macro Assembler -> Listing File. В поле Assembled Code Listing File вводим $(ProjectName).lst:







Выбираем Configuration Properties -> Linker -> Advanced. В поле Image Has Safe Exception Handlers выбираем значение No. Жмем ОК:







На этом этапе проект можно считать созданным. Написание кода рассмотрено в секции Тонкости вызова методов между С++ и Asm.





Только текстВключаем Visual Studio, выбираем File -> New -> Project....



Выбираем шаблон Win32 Console Application, кликаем ОК.



Жмем Next.



Ставим галочку напротив Empty project и жмем Finish.



Создаем исходники. Для этого делаем правый клик на Source Files, выбираем Add -> New Item....



Выбираем C++ File и жмем Add.



Аналогично, создаем *.asm файл (просто меняем расширение в поле Name).



Важно: имена файлов должны быть разными(не учитывая расширение), иначе при создании файлов *.obj возникнет проблема перезаписи одного объектного файла другим.



Теперь настройки. Делаем правый клик на проекте, выбираем Build Dependencies -> Build Customizations...



Ставим галочку напротив masm и жмем ОК.



Делаем правый клик на файле *.asm, выбираем Properties...



В поле Item Type выбираем Microsoft Macro Assembler и жмем ОК.



Выбираем Project -> Properties...



Выбираем Configuration Properties -> Microsoft Macro Assembler -> Listing File. В поле Assembled Code Listing File вводим $(ProjectName).lst.



Выбираем Configuration Properties -> Linker -> Advanced. В поле Image Has Safe Exception Handlers выбираем значение No. Жмем ОК.



На этом этапе проект можно считать созданным. Написание кода рассмотрено в секции Тонкости вызова методов между С++ и Asm.




[b]Настройка подсветки синтаксиса[/b]


Существует аддон для Visual Studio — asmHighlighter, однако на момент написания статьи версии для VS2013 не существовало. Однако, просмотрев раздел Discussions, я нашел сообщение пользователя Trass3r, который, к счастью, поделился репозиторием с версией аддона для VS2013. После установки Visual Studio SDK мне удалось собрать проект и теперь *.vsix пакет есть в свободном доступе.




[b]Тонкости вызова методов между С++ и Asm[/b]


Для того, чтоб избежать ошибок компиляции и/или связывания нужно помнить следующее:

  1. Если надо вызывать из ассемблера библиотечные методы, достаточно в начале секции кода указать, какие именно методы мы собираемся использовать.



    EXTRN printf : proc ;we'll use printf


    Далее можно просто использовать call:



    ;printf(ebx,eax)
    push eax;
    push ebx
    call printf
    add esp, 8 ;pop x2
  2. Если же надо вызывать пользовательские методы, то кроме п.1 надо еще писать extern «C» перед определением метода.



    extern "C"
    void* readName()
    {
    char* name = (char*)calloc(1, 255);
    scanf("%s", name);
    while (getchar() != 'n');
    return name;
    }


    Соответственно, в *.asm файле:

    EXTRN readName : proc ;and void* readName()
    и

    call readName ;eax = readName()


  3. В случае использования Asm-методов в C++ достаточно лишь указать прототип:



    extern "C"
    {
    void sayHello();
    }


    Данный прототип соответствует такому объявлению Asm-метода:



    sayHello PROC

    call readName ;eax = readName()
    lea ebx, helloFormat ;ebx = &helloFormat

    ;printf(ebx,eax)
    push eax
    push ebx
    call printf
    add esp, 8 ;pop x2

    retn

    sayHello ENDP


Собственно, полный исходный код примера:



Source.cpp#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

extern "C"
{
void sayHello();
}

void main()
{
printf("Hello, what is your name?n");
sayHello();
while (getchar() != 'n');
}
extern "C"
void* readName()
{
char* name = (char*)calloc(1, 255);
scanf("%s", name);
while (getchar() != 'n');
return name;
}




AsmSource.asm.686
.MODEL FLAT, C
.STACK
.DATA
;-----------Local data------------------------------
helloFormat BYTE "Hello, %s!", 10, 13, 0
.CODE
;-----------External usage--------------------------
EXTRN printf : proc;// we'll use printf
EXTRN readName : proc;//and void* readName()
;-----------Function definitions--------------------
sayHello PROC

call readName; eax = readName()
lea ebx, helloFormat; ebx = &helloFormat

;printf(ebx,eax)
push eax
push ebx
call printf
add esp, 8;pop x2

retn

sayHello ENDP

END







[b]Приложение[/b]


Готовый шаблон проекта можно найти здесь.

Пакет для подсветки asm синтаксиса можно найти здесь.

Original source: habrahabr.ru (comments, light).

Читать дальше


--------------------

Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

Рекламное место сдается Рекламное место сдается
Текстовая версия Сейчас: 18.8.2019, 0:36
Рейтинг@Mail.ru
Яндекс.Метрика Яндекс цитирования