Is it possible to compile assembly code in MSVC++? - visual-c++

Is it possible to create, edit, link, compile (is compile the word?) etc. assembly code in MSVC++?
Also, if it's not possible, how can I create an .exe out of plain text, ie: convert the text into whatever format is required to use assembly code, then turn the assembly code into an .exe. (I'd say compile, but I don't think that is the correct word here).
And finally, what are some good places to begin learning assembly code? Written in a way that someone who has little experience can use.
I know some of these questions are probably very stupid, but I have absolutely no experience in assembly code and am not exactly sure where to start.

On x86, yes. You can use the __asm keyword to put assembly inline in your standard source files, and use the normal MS compile/link tools to compile everything together.
On x64 (or x86), you may need to use the ML and ML64 command line compilers for assembly.

Visual Studio provides the __asm keyword for compiling inline assembly in c and c++. There is also a good discussion here on the use of inline assembly. However if you are just talking about compiling assembly on it's own I'm not sure if Visual C++ is the correct tool however I'm pretty sure visual studio ships with the MASM assembler.

In short, yes.
According to Wikipedia, MASM has been shipped with all versions of Visual C later than VC6, and is also available in the Windows Driver Developer Kit. Versions supporting 16-bit real and protected modes, 32-bit, and 64-bit are all supported.

You can use the __asm keyword to write inline assembly.
pcasm-book(pdf) is a good tutorial to start assembly code programming.

Yes, sort of.
C:\Program Files\Microsoft Visual Studio 9.0\vc\bin>ml
Microsoft (R) Macro Assembler Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
usage: ML [ options ] filelist [ /link linkoptions]
Run "ML /help" or "ML /?" for more info
You'd use the macro assembler. I don't know if Visual Studio will automatically "do the right thing" with .asm files, though, but you can certainly edit them with it and assemble them with ml.exe.
A good place to start learning assembly language might actually be by learning about reverse engineering.

Look for information on the C++ 'asm' keyword. It may be compiler specific, but I know VC++ supports it.

Related

C/C++ compilers (Windows)

I don't quite understand the difference between the following C/C++ compilers: GCC, MinGW, Cygwin and MSVC. Are the MinGW and Cygwin implementations of GCC or something entirely different? If I intend to compile for Windows, do I ever need anything other than the MSVC (Visual Studio) compiler?
GCC for Windows is mostly useful for makefiles and code written with gcc-specific non-portable syntax.
cygwin is not a compiler, it's a set of libraries that create a Linux-like environment inside Windows, and common linux tools compiled with those libraries.. It is useful for code written with Unixisms (expect files to behave a certain way, or assume the directory separator is /, or assume Linux paths).
If you have pure Windows code, you'll be happiest with Visual C++ (MSVC). Or, if that doesn't optimize well enough, the Intel C++ compiler.
Visual C++ also works well for portable ISO-conformant code... but Microsoft is a little behind the curve on implmenting C++11 and C++14 features. So that's another reason you might want to use gcc (or clang).

GNU g++ inline assembly block like Apple g++/Visual C++?

I am currently following a course at my University in which, at this stage, we learn about the assembler code behind certain C/C++ constructs.
The workflow usually goes like this: the lab assistant briefly speaks about a topic, we figure out the quirks and then solve some totally random problem using inline assembly.
(For example: He briefly talks about how struct (members) are stored in memory, we figure out the pattern and then we write the solution using inline assembly to a simple problem in which we use a struct.)
The lab assistant (as well as the rest of the group) is using the Visual C++ compiler and debugger (for disassembly) for his demonstrations however I cannot use it due to ethical reasons and thus I opted for g++ and gdb.
What I find awkward about g++'s inline assembly compared to Visual C++ is the fact that:
If I want to write a 'block' of inline assembly I have two options: Have a single asm("..") construct in which each instruction is preceded by a \n\t (leads to a lot of clutter). Or have each instruction in its own asm("..") block (leads to a lot of typing).
If I want to reference a local variable in the inline assembly I have to either use the extended syntax or reference it by using offsets to esp/ebp.
In respect to the two issues above I prefer the Visual C++'s inline assembly style in which in order to write an asm block all I have to do is __asm { .. } and write each instruction on a new line and in order to reference a variable I just have to write its name.
Throughout my searches I have discovered that Apple's g++ supports the same syntax as Visual C++ with a switch (-fasm-blocks) however this does not seem to be the case for GNU g++.
In the hopes that I might have missed something I am asking here if it is possible to compile Visual C++ like inline assembly blocks under GNU g++.
The syntax you are referring to is not Microsoft specific. As you have found, Apple had it too (although Apple gave up on GCC and switched to Clang). AFAIK, Metrowerks supports the same syntax. GCC does not support it (probably because GCC guys believe that GCC is so good that nobody needs to write assembly anymore :-)). However, there is no need to type \n\t all the time, you can replace it with ;. For example:
void foo()
{
asm("xor %eax,%eax;"
"rep; nop;"
"nop;"
"sfence;"
"nop;");
}
Hope it helps. Good Luck!

compiling visual C++ code in linux?

i have a visual C++ program which performs image matching. I am using openCV. I am looking to run the exe on a linux server. But i dont know how to compile visual C++ code in linux?
Can anyone plz help me in this regard . . .
If you did things smartly while writing the C++ code in MSVC, you isolated all platform-dependent code (i.e., Microsoft extensions to C++ and uses of Windows-only libraries) from the rest right from the start, and know exactly where to do the modifications to make it run on Linux as well.
Unfortunately, your question hints at this being your first attempt at cross-platform coding, and in that case, you probably littered Microsoft-isms all over your code, and have to pick through them one by one. Start the compiler, have a look at its error messages, and go from there. Good luck, it will be a pain, but also a very valuable lesson for your next project.
(I'm not finger-pointing at MSVC here. The very same is true for people who litter their code with GNU-isms and then want to have it compile on MSVC...)
The usual construct looks like this:
#if defined( _MSC_VER )
// Microsoft version
#elif defined( __GNUC__ )
// GCC version
#else
#error Platform / compiler not supported.
#endif
Edit: In case it is not obvious, the idea is to keep the ifdef'ed code above at an absolute minimum. Use typedef's, forwarding functions (i.e., log() to use either Unix or Windows logging), or - if all else fails - macros. Don't use the above all over the code, isolate it in a few header / implementation files, kept in a separate source folder.
You will also want to familiarize yourself with Makefiles (shameless plug: Makefile tutorial) or CMake, because MSVC project files don't work on Linux (obviously).
There's also winelib and stuff. Point your build system to using winegcc/wineg++ as your compiler, and go for it. It can compile a fairly large subset of windows programs. This should be a good option if all you need is to get one or two programs to work.

LLVM and visual studio .obj binary incompatibility

Does anyone know if LLVM binary compatibility is planned for visual studio combiled .obj and static .lib files?
Right now I can only link LLVM made .obj files with dynamic libs that loads a DLL at runtime (compiled from visual studio).
While there probably is very small chances that binary compatibility will happen between the two compilers, does anybody know why it is so difficult achieving this between compilers for one platform?
As Neil already said, the compatibility includes stuff like calling convention, name mangling, etc. Though these two are the smallest possible problems. LLVM already knows about all windows-specific calling conventions (stdcall, fastcall, thiscall), this is why you can call stuff from .dll's.
If we speak about C++ code then the main problem is C++ ABI: vtable layout, rtti implementation, etc. clang follows Itanium C++ ABI (which gcc use, for example, among others), VCPP - doesn't and all these are undocumented, unfortunately. There is some work going in clang in this direction, so stuff might start to work apparently. Note that most probably some parts will never be covered, e.g. seh-based exception handling on win32, because it's patented.
Linking with pure C code worked for ages, so, you might workaround these C++ ABI-related issues via C stubs / wrappers.
Apart from anything else, such as calling conventions, register usage etc, for C++ code to binary compatible the two compilers must use the same name-mangling scheme. These schemes are proprietory (so MS does not release the details if its scheme) and are in any case in a constant state of flux.

Why does MSVC not support inline assembly for AMD64 and Itanium targets?

Yesterday I learned that inline assembly (with the __asm keyword) is not supported under Microsoft Visual C++ when compiling for AMD64 and Itanium targets.
Is that correct? And if so, does anyone know why they would not support inline assembly for those targets? It seems like a rather big feature to just drop...
Correct, it still isn't supported in VS 2010 Beta 1. My guess is that inline assembly is just too difficult to implement: the way Microsoft implemented it, it integrates with the surrounding C code so that data can flow in and out of the C code, and appropriate glue code is automatically injected. For that, the C compiler actually needs to understand the assembler code; they just haven't implemented that for AMD64 and Itanium.
It seems like a rather big feature to just drop...
It's quite easy to call a function written with an assembler, as long as you follow C conventions. This tutorial explains how.

Resources