Для работы с MASM надо установить для Visual Studio инструменты разработки для C/C++. Поэтому после загрузки программы установщика Visual Studio запустим ее и в окне устанавливаемых опций выберем пункт Разработка классических приложений на C++ :
Visual Studio включает как 32-разрядные, так и 64-разрядные версии MASM. 32-раздяная версия представляет файл ml.exe , а 64-разрядная — файл ml64.exe . Точное расположение файлов может варьироваться от версии Visual Studio. Например, в моем случае это папка C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.35.32215binHostx64x64
Для использования MASM64 перейдем к меню Пуск и в списке программ найдем пункт Visual Studio и подпункт x64 Native Tools Command Prompt for VS 2022
Создание проекта в Visual Studio с ассемблерным модулем
Нам должна открыться консоль. Введем в нее ml64 , и нам отобразится версия ассемблера и некоторая дополнительная информация:
********************************************************************** ** Visual Studio 2022 Developer Command Prompt v17.5.5 ** Copyright (c) 2022 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: ‘x64’ C:Program FilesMicrosoft Visual Studio2022Community>ml64 Microsoft (R) Macro Assembler (x64) Version 14.35.32217.1 Copyright (C) Microsoft Corporation. All rights reserved. usage: ML64 [ options ] filelist [ /link linkoptions] Run «ML64 /help» or «ML64 /?» for more info C:Program FilesMicrosoft Visual Studio2022Community>
Стоит отметить, что запуск этой этой утилиты фактически представляет запуск файла C:Program FilesMicrosoft Visual Studio2022CommunityVCAuxiliaryBuildvcvars64.bat — он по сути вызывает другой файл — vcvarsall.bat, который собственно и настраивает окружение для выполнения ассемблера.
Структура программы на ассемблере MASM
Типичная программа на MASM содержит одну или несколько секций, которые определяют, как содержимое программы будет располагаться в памяти. Эти секции начинаются с таких директив MASM, как .code или .data . Данные, используемые в программе, обычно определяются в секции .data . Инструкции ассембра определяются в секции .code .
В общем случае программа на ассемблере MASM имеет следующий вид:
.code main proc ret main endp end
Директива .code указывает MASM сгруппировать операторы, следующие за ней, в специальный раздел памяти, зарезервированный для машинных инструкций.
Ассемблер преобразует каждую машинную инструкцию в последовательность из одного или нескольких байт. CPU интерпретирует эти значения байт как машинные инструкции во время выполнения программы.
Hello World на Ассемблере (x86)
Далее с помощью операторов main proc определяется процедура main. Операторы main endp указывают на конец функции main. Между main proc и main endp располагаются выполняемые инструкции ассемблера. Причем в самом конце функции идет инструкция ret , с помощью которой выполнение возвращается в окружение, в котором была вызвана даннуа процедура.
В конце файла кода идет инструкция end
Программа может содержать комментарии, которые располагаются после точки с запятой:
.code ; начало секции с кодом программы main proc ; Функция main ret ; возвращаемся в вызывающий код main endp ; окончание функции main end ; конец файла кода
Комментарии на работу программы никак не влияют и при компиляции не учитываются.
Компиляция программы
Компиляция программы на MASM обычно происходит в командной строке. Например, воспользуемся кодом выше и напишем простейшую программу на ассемблере, которая ничего не делает. Для этого определим на жестком диске папку для файлов с исходным кодом. Допустим, она будет называться C:asm . И в этой папке создадим новый файл, который назовем hello.asm и в котором определим следующий код:
.code ; начало секции с кодом программы main PROC ; Функция main ret ; возвращаемся в вызывающий код main ENDP END ; конец файла кода
Откроем программу x64 Native Tools Command Prompt for VS 2022 и перейдем в ней к папке, где располагается файл hello.asm. Затем выполним следующую команду
ml64 hello.asm /link /entry:main
В данном случае вызываем приложение ml64.exe и передаем ему для компиляции файл hello.asm. А флаг /link указывает MASM скомпоновать скомпилированный файл в файл приложения exe, а все дальнейшие параметры (в частности, параметр /entry:main ) передаются компоновщику. Параметр /entry:main передает компоновщику имя основной процедуры/функции, с которой начинается выполнение программы. Компоновщик сохраняет этот адрес этой процедуры/функции в специальном месте исполняемого файла, чтобы Windows могла определить начальный адрес основной программы после загрузки исполняемого файла в память.
В результате ассемблер скомпилирует ряд файлов
********************************************************************** ** Visual Studio 2022 Developer Command Prompt v17.5.5 ** Copyright (c) 2022 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: ‘x64’ C:Program FilesMicrosoft Visual Studio2022Community>cd c:asm c:asm>ml64 hello.asm /link /entry:main Microsoft (R) Macro Assembler (x64) Version 14.35.32217.1 Copyright (C) Microsoft Corporation. All rights reserved. Assembling: hello.asm Microsoft (R) Incremental Linker Version 14.35.32217.1 Copyright (C) Microsoft Corporation. All rights reserved. /OUT:hello.exe hello.obj /entry:main c:asm>
В итоге в каталоге программы будут сгенерированы объектный файл hello.obj и собственно файл программы — hello.exe.
Источник: metanit.com
Assembler вместе с C++ в Visual Studio 2013
2015-03-10 в 13:25, admin , рубрики: c++, Visual Studio, visual studio 2013, Программирование
Идея этой статьи отнюдь не новая, но, поскольку мне пришлось потратить два дня на разбор всех ошибок компиляции и линковки, а также поиск ответов на свои вопросы, решил, что читатели Хабра заслуживают на экономию времени. Тех, кто желает быстро узнать, как использовать одновременно *.asm и *.cpp файлы в проекте, как вызывать методы C++ из ассемблера и наоборот, прошу пожаловать под кат.
Предисловие
Началось все с прочтения мной публикации «Ассемблер для Windows используя Visual Studio» (отсюда и почти идентичный код). Там рассмотрено использование Visual Studio 2005, а для 2013-й студии процесс похожий, но есть несколько отличий, которые заставят неподготовленного пользователя долго искать решения всех проблем со сборкой.
Содержание
- TL;DR
- Создание проекта
- Настройка подсветки синтаксиса
- Тонкости вызова методов между С++ и Asm
- Приложение
TL;DR
Для тех, у кого совсем нет времени на прочтение: в конце статьи (в приложении) есть ссылка на готовый шаблон проекта и на аддон для подсветки синтаксиса.
Создание проекта
Иллюстрированная версия
Включаем Visual Studio, выбираем File -> New -> Project. :
Выбираем шаблон Win32 Console Application, кликаем ОК:
Ставим галочку напротив 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, кликаем ОК.
Ставим галочку напротив 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 — asmHighlighter, однако на момент написания статьи версии для VS2013 не существовало. Однако, просмотрев раздел Discussions, я нашел сообщение пользователя Trass3r, который, к счастью, поделился репозиторием с версией аддона для VS2013. После установки Visual Studio SDK мне удалось собрать проект и теперь *.vsix пакет есть в свободном доступе.
Тонкости вызова методов между С++ и Asm
Для того, чтоб избежать ошибок компиляции и/или связывания нужно помнить следующее:
-
Если надо вызывать из ассемблера библиотечные методы, достаточно в начале секции кода указать, какие именно методы мы собираемся использовать.
EXTRN printf : proc ;we’ll use printf
Далее можно просто использовать call:
;printf(ebx,eax) push eax; push ebx call printf add esp, 8 ;pop x2
extern «C» void* readName()
Соответственно, в *.asm файле:
EXTRN readName : proc ;and void* readName()
call readName ;eax = readName()
extern «C»
Данный прототип соответствует такому объявлению Asm-метода:
sayHello PROC call readName ;eax = readName() lea ebx, helloFormat ;ebx = 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 #include extern «C» < void sayHello(); >void main() < printf(«Hello, what is your name?n»); sayHello(); while (getchar() != ‘n’); >extern «C» void* readName()
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 = printf(ebx,eax) push eax push ebx call printf add esp, 8;pop x2 retn sayHello ENDP END
Приложение
Готовый шаблон проекта можно найти здесь.
Пакет для подсветки asm синтаксиса можно найти здесь.
Источник: www.pvsm.ru
Как запустить программу на ассемблере в visual studio
Полный спектр компьютерных услуг!
Загрузка. Пожалуйста, подождите.
Сообщение сайта
(Сообщение закроется через 2 секунды)
Внимание!
Разработка / [Из песочницы] Ассемблер для Windows используя Visual Studio
Decker
Просмотр профиля
6.1.2011, 3:01
Группа: Главные администраторы
Сообщений: 14349
Регистрация: 12.10.2007
Из: Twilight Zone
Пользователь №: 1
Многие из нас изучали ассемблер в университете, но почти всегда это ограничивалось простыми алгоритмами под DOS. При разработке программ для Windows может возникнуть необходимость написать часть кода на ассемблер, в этой статье я хочу рассказать вам, как использовать ассемблер в ваших программах под Visual Studio 2005.
Создание проекта
В статье мы рассмотрим как вызывать ассемблер из С++ кода и обратно, передавать данные, а также использовать отладчик встроенный в Visual Studio 2005 для отладки кода на ассемблер.
Для начала нам нужно создать проект. Включаем Visual Studio, выбираем File > New > Project. В Visual Studio нет языка ассемблер в окне выбора типа проекта, поэтому создаем С++ Win32 проект. В окне настроек нового проекта выбираем «Empty Project».
По умолчанию Visual Studio не распознает файлы с кодом на ассемблер. Для того чтобы включить поддержку ассемблер нам необходимо настроить в проекте условия сборки указав какой программой необходимо компилировать файлы *.asm. Для этого выбираем пункт меню «Custom Build Rules. ».
В открывшемся окне мы можем указать специальные правила компиляции для различных файлов, Visual Studio 2005 уже имеет готовое правило для файлов *.asm, нам необходимо лишь включить его, установив напротив правила «Microsoft Macro Assembler» галочку.
Добавление исходного кода
Перейдем к написанию исходного кода нашего проекта. Начнем с добавления исходного кода на c++. Добавим новый файл в папку Source Files. В качестве Template выбираем C++ File и вводим желаемое имя файла, например main.cpp. Напишем функцию, которая будет считывать имя введенное пользователем, оформив это в виде функции readName() которая будет возвращать ссылку на считанное имя. Мы получим примерно следующее содержимое файла:
void main ()
printf(«Hello, what is your name?n»);
>
Теперь, когда мы знаем имя пользователя мы можем вывести приветствие, его будет выводить функция sayHello() которую мы напишем на ассемблер, чтобы использовать эту функцию сначала мы должны указать что она будет определена в другом файле, для этого добавим блок к main.cpp:
Этот блок говорит компилятору, что функция sayHello() будет объявлена в другом файле и будет иметь правила вызова «C». Компилятор C++ искажает имена функций так, что указание правил вызова обязательно. Кроме того мы хотим использовать функцию readName() из функции sayHello(), для этого необходимо добавить extern «C» перед определением функции readName(), это позволит вызывать эту функцию из других файлов используя правила вызова «C».
Пришло время добавить код на ассемблер, для этого добавим в Source Folder новый файл. Выбираем тип Text File (.txt) и в поле название заменяем .txt на .asm, назовем наш файл hello.asm. Объявим функцию sayHello() и укажем внешние функции, которые мы хотим использовать. Получим следующий код:
.686
.MODEL FLAT, C
.STACK
.DATA
helloFormat BYTE «Hello %s!»,10,13,0
.CODE
readName PROTO C
printf PROTO arg1:Ptr Byte, printlist: VARARG
sayHello PROC
invoke readName
invoke printf, ADDR helloFormat, eax
ret
sayHello ENDP
END
Теперь мы можем запустить проект, для этого просто выбираем Debug > Start Without Debugging или нажимаем комбинацию Ctrl-F5. Если все сделано верно, вы увидите окно программы:
Немного усложним задачу, попробуем написать на ассемблер функцию принимающую параметр и возвращающую значение. Для примера напишем функцию calcSumm() которая будет принимать целое число и возвращать сумму его цифр. Изменим наш код на С++ добавив в него информацию о функции calcSumm, ввод числа и собственно вызов функции.
Добавим функцию в файл hello.asm, возвращаемое значение помещается в eax, параметры объявляются после ключевого слова PROC. Все параметры можно использовать в коде процедуры, они автоматически извлекутся из стека. Также в процедурах можно использовать локальные переменные. Вы не можете использовать эти переменные вне процедуры. Они сохранены в стеке и удаляются при возврате из процедуры:
.686
.MODEL FLAT, C
.STACK
.DATA
helloFormat BYTE «Hello %s!»,10,13,0
.CODE
readName PROTO C
printf PROTO arg1:Ptr Byte, printlist: VARARG
sayHello PROC
invoke readName
invoke printf, ADDR helloFormat, eax
ret
sayHello ENDP
Запустив проект мы увидим следующий результат выполнения:
Конечно в данной задаче нет ничего сложного и она вовсе не требует использования ассемблер. Более интересным будет рассмотреть, а что же нам дает Visual Studio для разработки на ассемблер. Попробуем включить режим отладки и установим точку остановки в hello.asm, запустим проект, мы увидим следующее:
Окно Disassembly (Debug > Windows > Disassembly) показываем команды ассемблер для данного объектного файла. Код который мы написали на С++ показывается черным цветом. Disassembled code показывается серым после соответствующего ему кода на C++/ассемблер. Окно Disassembly позволяет отлаживать код и осуществлять stepping по нему.
Окно регистров (Debug > Windows > Registers) позволяет посмотреть значение регистров.
Окно памяти (Debug > Windows > Memory) позволяет посмотреть дамп памяти, слева мы видим шестнадцатеричные адрес, справа шеснадцатеричные значения соответствующих ячеек памяти, можно перемещаться, вводя адрес в соответствующее поле в верху окна.
Original source: habrahabr.ru (comments).
Источник: dml.compkaluga.ru