I have created a program in visual studio to move values in the registry but i have no way of knowing whether the program actually worked since i cannot see the registr in visual studio 2017
I am running on visual studio 2017. I have a C++ Project that looks like this
extern "C" void doit();
void main()
{
doit();
}
and thsi is what my assembly file looks like
.586
.model flat ,c
.stack 100h
.data
.code
doit proc
mov eax, 8
mov ebx, 4
mov ecx, 6
mov edx, 12
add eax, ebx
add eax, edx
sub eax, ecx
doit endp
end
I would now please like to print or message box the values in these registrys so that i can know if the program works. Thx for the help
Related
I'm here to ask you some stuff about VS2017.
In the past I had used WinAsm for MASM and I never got problems with it.
However, when I'm trying to do something with MASM in VS2017, I always gonna get problems and stuff...
I've checked the whole internet about "how to set up VS for MASM", but nothing has helped me as I'm always getting troubles...
Is there any way to use Visual Studio 2017 for MASM32/64bit without any kind of headache?
Can someone give me the ultimate guide to set up VS2017 for assembly programming?
Thanks you very much and sorry for my weak english.
How to build a x64/x86-project with a standalone x64/x86 assembly file
1) Start Visual Studio (Community) 2017 and choose FILE - New - Project.
2) In the next window choose Empty Project.
3) Make sure, that the project is highlighted in the Solution Explorer and and choose PROJECT - Build Customizations....
4) In the next window tick masm(.targets,.props) and click on OK.
5) Choose PROJECT - Add New Item from the menu.
6) In the next window choose C++File(.cpp) and - IMPORTANT! - give it a name with an .asm extension. Click on Add.
7) Now you can fill the file with content.
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://learn.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
This is a 64-bit Console application that starts at the procedure main.
8) Change the Solution Platforms to x64
9) Choose PROJECT - Properties.
10) In the Properties window you have to complete two linker options:
Entry Point: main
SubSystem: Console (/SUBSYSTEM:CONSOLE)
Choose at the left side Configuration Properties - Linker - All Options , change both options at once and click OK.
11) Build and run the .exe with CTRL-F5. The application will be opened in a new window.
Now overwrite Source.asm with a 32-bit Console application:
.MODEL flat, stdcall
; https://learn.microsoft.com/en-us/cpp/assembler/masm/proto
GetStdHandle PROTO STDCALL, ; https://learn.microsoft.com/en-us/windows/console/getstdhandle
nStdHandle: SDWORD
WriteFile PROTO STDCALL, ; https://learn.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://learn.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-exitprocess
dwExitCode: DWORD ; return code
.DATA ; https://learn.microsoft.com/en-us/cpp/assembler/masm/dot-data
Hallo db "Hello world!",13,10
.DATA? ; https://learn.microsoft.com/en-us/cpp/assembler/masm/dot-data-q
lpNrOfChars dd ?
.CODE ; https://learn.microsoft.com/en-us/cpp/assembler/masm/dot-code
main PROC ; learn.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://learn.microsoft.com/en-us/cpp/assembler/masm/end-masm
Change the Solution Platforms to x86 (No. 8 above) and complete the project properties with SubSystem: Console (/SUBSYSTEM:CONSOLE) (No. 10 above). You must not set the Entry point, because ml32 expects the entry point after the END directive (END main). Build and run the .exe with CTRL-F5.
I'm here to ask you some stuff about VS2017.
In the past I had used WinAsm for MASM and I never got problems with it.
However, when I'm trying to do something with MASM in VS2017, I always gonna get problems and stuff...
I've checked the whole internet about "how to set up VS for MASM", but nothing has helped me as I'm always getting troubles...
Is there any way to use Visual Studio 2017 for MASM32/64bit without any kind of headache?
Can someone give me the ultimate guide to set up VS2017 for assembly programming?
Thanks you very much and sorry for my weak english.
How to build a x64/x86-project with a standalone x64/x86 assembly file
1) Start Visual Studio (Community) 2017 and choose FILE - New - Project.
2) In the next window choose Empty Project.
3) Make sure, that the project is highlighted in the Solution Explorer and and choose PROJECT - Build Customizations....
4) In the next window tick masm(.targets,.props) and click on OK.
5) Choose PROJECT - Add New Item from the menu.
6) In the next window choose C++File(.cpp) and - IMPORTANT! - give it a name with an .asm extension. Click on Add.
7) Now you can fill the file with content.
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://learn.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
This is a 64-bit Console application that starts at the procedure main.
8) Change the Solution Platforms to x64
9) Choose PROJECT - Properties.
10) In the Properties window you have to complete two linker options:
Entry Point: main
SubSystem: Console (/SUBSYSTEM:CONSOLE)
Choose at the left side Configuration Properties - Linker - All Options , change both options at once and click OK.
11) Build and run the .exe with CTRL-F5. The application will be opened in a new window.
Now overwrite Source.asm with a 32-bit Console application:
.MODEL flat, stdcall
; https://learn.microsoft.com/en-us/cpp/assembler/masm/proto
GetStdHandle PROTO STDCALL, ; https://learn.microsoft.com/en-us/windows/console/getstdhandle
nStdHandle: SDWORD
WriteFile PROTO STDCALL, ; https://learn.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://learn.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-exitprocess
dwExitCode: DWORD ; return code
.DATA ; https://learn.microsoft.com/en-us/cpp/assembler/masm/dot-data
Hallo db "Hello world!",13,10
.DATA? ; https://learn.microsoft.com/en-us/cpp/assembler/masm/dot-data-q
lpNrOfChars dd ?
.CODE ; https://learn.microsoft.com/en-us/cpp/assembler/masm/dot-code
main PROC ; learn.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://learn.microsoft.com/en-us/cpp/assembler/masm/end-masm
Change the Solution Platforms to x86 (No. 8 above) and complete the project properties with SubSystem: Console (/SUBSYSTEM:CONSOLE) (No. 10 above). You must not set the Entry point, because ml32 expects the entry point after the END directive (END main). Build and run the .exe with CTRL-F5.
I'm using Visual Studio 2017 Community to build a test console C++ application. I need to include an assembly function into that project:
extern "C" void* __fastcall getBaseFS(void);
To include an asm file I right-clicked the project and went to "Build dependencies" -> "Build Customization" and checked "masm" in the list there.
I can then add an asm file by right-clicking my project -> Add New item -> and then add "asm_x64.asm" file where I write my x86-64 asm code:
.code
getBaseFS PROC
mov ecx, 0C0000100H ; IA32_FS_BASE
rdmsr
shl rdx, 32
or rax, rdx
ret
getBaseFS ENDP
END
This works in a 64-bit project.
The problem is that when I switch solution platform from x64 to x86:
my asm file needs to change. So in a sense I need to include a different "asm_x86.asm" file into compilation that is used only for x86 builds vs. x64 builds.
What's the best way to automate this switch?
OK, thanks to Michael Petch, I got it solved. Had to put both x64 and x86 code in one .asm file.
(There's another proposed option to deal with build configuration, but I prefer the method I'm showing here. I had a bad luck with those build configurations disappearing when solutions were moved from computer to computer.)
So, I'm not sure why using IFDEF RAX works, and Microsoft's own proposed ifndef X64 doesn't. But oh well. If anyone knows, please post a comment.
asm_code.asm file:
IFDEF RAX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WinAPI to call
extrn Beep : proc
.data
align 8
beep_freq:
dq 700 ; hz
beep_dur:
dq 200 ; ms
str_from:
db "Hail from x64 asm", 0
.code
useless_sh_t_function__get_GS_a_string_and_beep PROC
; parameter = CHAR** for a string pointer
; return = value of GS register selector
mov rax, str_from
mov [rcx], rax
mov rdx, qword ptr [beep_dur]
mov rcx, qword ptr [beep_freq]
call Beep
mov rax, gs
ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP
ELSE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.686p
.XMM
.model flat, C
.data
align 4
beep_freq dd 700 ; hz
beep_dur dd 200 ; ms
str_from db "Hail from x86 asm", 0
.code
; WinAPI to call
extrn stdcall Beep#8 : proc
useless_sh_t_function__get_GS_a_string_and_beep PROC
; parameter = CHAR** for a string pointer
; return = value of GS register selector
mov eax, [esp + 4]
mov [eax], OFFSET str_from
push dword ptr [beep_dur]
push dword ptr [beep_freq]
call Beep#8
mov eax, gs
ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP
ENDIF
END
main.cpp file:
#include "stdafx.h"
#include <Windows.h>
extern "C" {
size_t useless_sh_t_function__get_GS_a_string_and_beep(const CHAR** ppString);
};
int main()
{
const char* pString = NULL;
size_t nGS = useless_sh_t_function__get_GS_a_string_and_beep(&pString);
printf("gs=0x%Ix, %s\n", nGS, pString);
return 0;
}
Good that you found a way to handle your use case.
However, if you have more asm files, or only need them for some build types, you could also change the settings for each individual file for the parts where it differs from the project defaults.
Just right-click a file name to get to its individual properties.
To have an asm file included in x64 builds only, you can use these settings:
And then exclude it from 32-bit builds:
These settings are available for all file type, not only for .asm files.
It seems that Visual Studio debugger (I've checked VS 2015 and VS 2017) skips constructors and assignment operators in the base class. If I create a new C++ Win32 console application project with the following code
#include <iostream>
struct B
{
B() { std::cout << "ctor"; }
};
struct S : B { };
int main()
{
S s1;
return 0;
}
I cannot step into B::B(), "ctor" is printed and the debugger goes to the "return 0;" line. In the disassembly the "call S::S (01713D4h)" is followed by a piece of code that is not attributed to any source ("Source not available"):
00E51DF0 push ebp
00E51DF1 mov ebp,esp
00E51DF3 sub esp,0CCh
00E51DF9 push ebx
00E51DFA push esi
00E51DFB push edi
00E51DFC push ecx
00E51DFD lea edi,[ebp-0CCh]
00E51E03 mov ecx,33h
00E51E08 mov eax,0CCCCCCCCh
00E51E0D rep stos dword ptr es:[edi]
00E51E0F pop ecx
00E51E10 mov dword ptr [this],ecx
00E51E13 mov ecx,dword ptr [this]
00E51E16 call B::B (0E51389h)
How can I step into B::B() (without using a breakpoint)?
I got the same issue as yours, not find the VS settings which could impact the debugger tool, so I help you report this issue to the product team here:
https://developercommunity.visualstudio.com/content/problem/77978/vs-debugger-skips-ctors-in-base-class.html.
If possible, you could also add your comment and vote that report directly. If I got any update from the product team, I will share it here.
I wanted to compile my strlen_sse.asm to accomplish a function strlen_sse,which has the same function as strlen but more quick. And my code is below:
.CODE
EQUAL_EACH = 00001000b
strlen_sse PROC
;ecx = string
mov eax, -16
mov edx, ecx
pxor xmm0, xmm0
STRLEN_LOOP:
add eax, 16
PcmpIstrI xmm0, dqword[edx+eax], EQUAL_EACH
jnz STRLEN_LOOP
add eax, ecx
ret
strlen_sse ENDP
END
I have set the command line and other properties like the picture below:
In the picture 命令行 is what the command line is in Chinese. and 输出 is the same as Output
When I built the project I got messages below:
1> Performing Custom Build Tools
1> Microsoft (R) Macro Assembler (x64) Version 14.00.23026.0
1> Copyright (C) Microsoft Corporation. All rights reserved.
1>
1> Assembling: strlen_sse.asm
1>strlen_sse.asm(13): error A2006: undefined symbol : dqword
How to solve it?
I'm not sure what do you mean by dqword. I guess you are trying to use assembly code intended for some other assembler. I should use XMMWORD PTR prefix for a memory operand of 128-bit size in masm.
Here is the modified code which compiles with ml.exe and ml64.exe:
tmp SEGMENT
strlen_sse PROC
;ecx = string
mov eax, -16
mov edx, ecx
pxor xmm0, xmm0
STRLEN_LOOP:
add eax, 16
PcmpIstrI xmm0, xmmword ptr [edx+eax], 00001000b
jnz STRLEN_LOOP
add eax, ecx
ret
strlen_sse ENDP
tmp ENDS
END
Beware: I have no idea whether it works properly or not.