Программирование на ассемблере - WinAsm vs Visual Studio 2017
Я здесь, чтобы спросить вас кое-что о VS2017.
В прошлом я использовал WinAsm для MASM, и у меня никогда не было проблем с ним.
Однако, когда я пытаюсь что-то сделать с MASM в VS2017, у меня всегда будут проблемы и все такое...
Я проверил весь интернет на предмет "как настроить VS для MASM", но ничто не помогло мне, потому что у меня всегда возникают проблемы...
Есть ли способ использовать Visual Studio 2017 для MASM32/64bit без головной боли?
Может кто-нибудь дать мне полное руководство по настройке VS2017 для программирования на ассемблере?
Большое спасибо и извините за мой слабый английский.
1 ответ
Как создать x64/x86-проект с помощью отдельного файла сборки x64 / x86
1) Запустите Visual Studio (Community) 2017 и выберите FILE - New - Project
,
2) В следующем окне выберите Empty Project
,
3) Теперь выберите PROJECT - Build Customizations...
,
4) в следующем окне отметьте masm(.targets,.props)
и нажмите на OK
,
5) Выберите PROJECT - Add New Item
,
6) В следующем окне выберите C++File(.cpp)
и - ВАЖНО! - дать ему имя с .asm
расширение. Нажмите на Add
,
7) Теперь вы можете заполнить файл контентом.
Source.asm:
EXTERN GetStdHandle : PROC
EXTERN WriteFile : PROC
EXTERN ExitProcess : PROC
.DATA?
hFile QWORD ?
BytesWritten DWORD ?
.DATA
hello BYTE 'Hello world!', 13, 10
.CODE
main PROC
; https://blogs.msdn.microsoft.com/oldnewthing/20160623-00/?p=93735
sub rsp, 40 ; Shadow space (4 * 8) & 1 parameter (8 bytes)
; https://docs.microsoft.com/en-us/cpp/build/stack-allocation
and spl, -16 ; Align to 16
; https://msdn.microsoft.com/library/windows/desktop/ms683231.aspx
mov ecx, -11 ; DWORD nStdHandle = STD_OUTPUT_HANDLE
call GetStdHandle ; Call WinApi
mov hFile, rax ; Save returned handle
; https://msdn.microsoft.com/library/windows/desktop/aa365747.aspx
mov rcx, hFile ; HANDLE hFile (here: Stdout)
lea rdx, hello ; LPCVOID lpBuffer
lea r9, BytesWritten ; LPDWORD lpNumberOfBytesWritten
mov r8d, LENGTHOF hello ; DWORD nNumberOfBytesToWrite
mov qword ptr [rsp+32], 0 ; LPOVERLAPPED lpOverlapped = NULL
call WriteFile ; Call WinAPI
exit:
; https://msdn.microsoft.com/library/windows/desktop/ms682658.aspx
xor ecx, ecx ; Set RCX to null for return value
call ExitProcess ; Call WinAPI to exit
main ENDP
end
Это 64-битное консольное приложение, которое запускается при процедуре main
,
8) Изменить Solution Platforms
до х64
9) Выберите PROJECT - Properties
,
10) В окне "Свойства" необходимо указать два параметра компоновщика:
- Точка входа: главная
- Подсистема: Консоль (/SUBSYSTEM:CONSOLE)
Выберите на левой стороне Configuration Properties - Linker - All Options
, измените обе опции одновременно и нажмите OK
,
11) Создайте и запустите.exe с помощью CTRL-F5. Приложение будет открыто в новом окне.
Сейчас перезаписать Source.asm
с 32-битным консольным приложением:
.MODEL flat, stdcall
; https://docs.microsoft.com/en-us/cpp/assembler/masm/proto
GetStdHandle PROTO STDCALL, ; https://docs.microsoft.com/en-us/windows/console/getstdhandle
nStdHandle: SDWORD
WriteFile PROTO STDCALL, ; https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-writefile
hFile: DWORD, ; output handle
lpBuffer: PTR BYTE, ; pointer to buffer
nNumberOfBytesToWrite: DWORD, ; size of buffer
lpNumberOfBytesWritten: PTR DWORD, ; num bytes written
lpOverlapped: PTR DWORD ; ptr to asynchronous info
ExitProcess PROTO STDCALL, ; https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-exitprocess
dwExitCode: DWORD ; return code
.DATA ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-data
Hallo db "Hello world!",13,10
.DATA? ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-data-q
lpNrOfChars dd ?
.CODE ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-code
main PROC ; docs.microsoft.com/en-us/cpp/assembler/masm/proc
invoke GetStdHandle, -11 ; -> StdOut-Handle into EAX
invoke WriteFile, eax, OFFSET Hallo, LENGTHOF Hallo, OFFSET lpNrOfChars, 0
invoke ExitProcess, 0
main ENDP
END main ; https://docs.microsoft.com/en-us/cpp/assembler/masm/end-masm
Изменить Solution Platforms
в x86
(№ 8 выше) и заполните свойства проекта с помощью SubSystem: Console (/SUBSYSTEM:CONSOLE)
(№ 10 выше). Вы не должны устанавливать точку входа, потому что ml32 ожидает точку входа после END
директива (END main
). Создайте и запустите.exe с помощью CTRL-F5.