What assembly language does C code compile into in Visual Studio? - c

When I debug a C project, I can see all the assembly codes it compiles into. I want to know what assembly language that it. Is it NASM or MASM or something else? And if I use inline assembly, will I be able to use some other assembly language?

The code it compiles to is not assembly, but straight machine code, at least after link-time optimizations. What you see while debugging is on-the-fly disassembly of the machine code that is currently executing. As such, it has no additional structure, such as labels, macros, etc. such that you would expect to find in high-level assemblers, because this extra information is lost (or, more accurately, never present), when producing machine code.
If you meant the syntax, Visual Studio shows the assembly directives in Intel syntax, which is different from AT&T syntax, which is a default with GCC and GNU assembler.
In fact, it may also be gibberish. If you jmp out of alignment (x86 instructions are variable-length), or to a region that does not contain executable code, but rather data, the disassembler will try to make sense of the data, producing random assembly directives that don't mean anything.
This is actually quite common; see for example this image:
add byte ptr [rax], al is the attempted disassembly of bytes 00 00, which obviously does not represent actual executable code.

MSVC can compile binaries for x86, x86_64, ARM and Itanium. So it depends on your target and project settings

For X86 or X86-X64, Visual Studio includes ML.EXE (MASM 6.00 and later versions were renamed to ML.EXE) for 32 bit code and ML64.EXE for 64 bit code. On a VS project, you can right click on a file name, then properties, ... output files, ... assembly listing ... . The command line option for assembly listing is /Fa. Although called assembly only listing, it produces assembly code.

Related

Why is the assembly code generate by hello world in C not having a .code segment nor model tiny like x86 assembly does?

I'm learning assembly for 80x86 this semester. A typical asm file I write looks something like
.model tiny
.486
.data
#initializations
.code
.startup
#actual code
.exit
end
I was expecting a similar format when I created a .s file for a simple hello world. But I don't see any of the segments with their proper names and it's all very different. I compile using g++ -S -O0 hello.c
Why is the assembly for c so different than the assembly they make us write in class? Is the assembly I'm learning used by a different programming language? If I want to get the assembly version (that I'm used to) of hello world from some higher-level code, how do I do that?
The code does not match your command line. That is neither C (file name) nor C++ code (command line). That is assembly language.
Assembly language varies by tool (masm, tasm, nasm, gas, etc), and is not expected to be compatible nor standard in any way. Not talking about just intel vs at&t, all of the code, and this applies to all targets not just x86, easily seen with ARM and others.
You should try to use the assembler not a C nor C++ compiler as that creates yet another assembly language even though gcc for example will pass the assembly language on to gas it can pre-process it through the C preprocessor creating yet another programming language that is incompatible with the gnu assembler it is fed to.
x86 is the last if ever assembly language/instruction set you want to learn, if you are going to learn it then starting with the 8086/88 is IMO the preferred way, much more understandable despite the nuances. Since this appears to be a class you are stuck with this ISA and cannot chose a better first instruction set. (first, second, third...)
Very much within the x86 world, but also for any other target, expect that the language is incompatible between tools and if it happens to work or mostly work that is a bonus. Likewise there is no reason to assume that any tool will have a "masm compatible" or other mode, simply stating intel vs at&t is only a fraction of the language problem and is in no way expected to make the code port between tools.
Re-write the code for the assembly language used for the assembler is the bottom line.

Making assembly function inline in x64 Visual Studio

I know that MSVC compiler in x64 mode does not support inline assembly snippets of code, and in order to use assembly code you have to define your function in some external my_asm_funcs.asm file like that:
my_asm_func PROC
mov rax, rcx
ret
my_asm_func ENDP
And then in your .c or .h file you define a header for the function like that:
int my_asm_func(int x);
Although that solution answers many concerns, but I am still interested in making that assembly code function to be inline, in other words - after compilation I don't want any "calls" to my_asm_func, I just want this piece of assembly to be glued into my final compiled code. I tried declaring the function with inline and __forceinline keywords, but nothing seems to be helping. Is there still any way to do what I want?
No, there is no way to do what you want.
Microsoft's compiler doesn't support inline assembly for x86-64 targets, as you said. This forces you to define your assembly functions in an external code module (*.asm), assemble them with MASM, and link the result together with your separately-compiled C/C++ code.
The required separation of steps means that the C/C++ compiler cannot inline your assembly functions because they are not visible to it at the time of compilation.
Even with link-time code generation (LTCG) enabled, your assembly module(s) will not get inlined because the linker simply doesn't support this.
There is absolutely no way to get assembly functions written in a separate module inlined directly into C or C++ code.
There is no way that the inline or __forceinline keywords could do anything. In fact, there's no way that you could use them without a compiler error (or at least a warning). These annotations have to go on the function's definition (which, for an inline function, is the same as its declaration), but you can't put it on the function's definition, since that's defined in a separate *.asm file. These aren't MASM keywords, so trying to add them to the definition would necessarily result in an error. And putting them on the forward declaration of the assembly function in the C header is going to be similarly unsuccessful, since there's no code there to inline—just a prototype.
This is why Microsoft recommends using intrinsics. You can use these directly in your C or C++ code, and the compiler will emit the corresponding assembly code automatically. Not only does this accomplish the desired inlining, but intrinsics even allow the optimizer to function, further improving the results. No, intrinsics do not lead to perfect code, and there aren't intrinsics for everything, but it's the best you can do with Microsoft's compiler.
Your only other alternative is to sit down and play with various permutations of C/C++ code until you get the compiler to generate the desired object code. This can be very powerful in cases where intrinsics are not available for the instructions that you wish to be generated, but it does take a lot of time spent fidgeting, and you'll have to revisit it to make sure it continues to do what you want when you upgrade compiler versions.
Since the title mentions Visual Studio and not MSVC, I recommend installing Clang via the Visual Studio Installer. It can be used just like MSVC without needing to configure custom build tasks or anything and it supports inline assembly with Intel syntax and variables as operands.
Just select "LLVM (clang-cl)" in Platform Toolset from the General section of the property pages in your project and you're good to go.
Yes you can. Assemble your procedure as shellcode and extract the bytes, then include it in a buffer with RWX memory protection in your code. Call the code.

Getting Intel-syntax asm output from icc, instead of the default AT&T syntax?

I am stuck at a problem. I've been using gcc to compile/assemble my C code for a while and got used to reading Intel assembly syntax. I used the -masm=intel flag when generating the assembly files.
Yet recently, due to company migrations, they obtained Intel's icc, claiming it is better. So now I need to use icc, but it was strange that it has the default assembly syntax as AT&T. I tried to change it but it didn't work, so I contacted Intel support and they also don't know and each person gave me a contradicting answer.
Is there a way to integrate gcc and icc so that I use icc's compiling "superiority" while at the same time compiling to intel's syntax with gcc?
I am using ubuntu and got the icc version 12.x
This flag?
-use_msasm Support Microsoft style assembly language insertion
using MASM style syntax and, if requested, output assem-
bly in MASM format
https://web.archive.org/web/20120728043315/http://amath.colorado.edu/computing/software/man/icc.html
It seems that -masm=intel works in ICC just like Clang and GCC, at least in the current latest version in Compiler Explorer (13.0.1). I tried loading the sum over array example and it generates the below assembly
testFunction(int*, int):
xor eax, eax #2.11
test esi, esi #3.23
jle ..B1.18 # Prob 50% #3.23
movsxd rdx, esi #3.3
...
whereas specifying -use_msasm like in Steve-o's answer doesn't work at all
The official man page from Intel said that it's -use-msasm and not -use_msasm but that doesn't work either
-use-msasm (i32, i32em only)
Support Microsoft* style assembly language insertion using MASM style syntax and, if requested, output assembly in MASM format.
Note: GNU inline assembler (asm) code and Microsoft inline assembler (msasm) code cannot be used together in the same translation unit.
However that's for ICC 9.x in 2006 which was too long ago, and the option might have been changed somewhere between 9.x and 13.x
I dug a little bit further and realized that at least since ICC 16.0 the option is only for assembly blocks in source code and not for outputting Intel syntax
use-msasm
Enables the use of blocks and entire functions of assembly code within a C or C++ file.
Description
This option enables the use of blocks and entire functions of assembly code within a C or C++ file.
It allows a Microsoft* MASM-style inline assembly block not a GNU*-style inline assembly block.
Alternate Options
-fasm-blocks
As you can see it's just an alias for -fasm-blocks. Moreover the -use-asm option was deprecated although I don't know the fate of -use-msasm
References
Intel® C++ Compiler for Linux* - 9.x manuals
Intel® C++ Compiler 16.0 User and Reference Guide
Intel® C++ Compiler 17.0 Developer Guide and Reference

Using another assembler (MASM, NASM, TASM, etc.) with GCC

I've been looking through questions on here and the internet for a while now and I cannot seem to find out whether or not it is possible to do inline assembly with GCC using something other than GAS. I am trying to find if I can avoid using not only GAS's AT&T syntax (though, I know how to use Intel syntax with GAS) but the extended asm format. While this is not for a project or anything other than my own curiosity, I would really appreciate any help I can get (this is actually my first question here because I could not find an answer about it)! Also, if this makes any difference, I'm currently using DevC++ (for C code, not C++) on Windows.
Thanks,
Tom
You can link the output from an assembler (a ".o" or ".obj" file) with your C or C++ program. Put your assembler code in a text file. Your IDE or makefile will assemble it just as it would any c source file. The only tricky bit is learning how to interface between the two different systems.
You cannot use another inline assembly syntax with GCC. inline assembly is implemented by GCC literally including the assembly you write inline with its own (textual) assembly output, which it then sends to gas to be assembled. Since GCC doesn't know how to change the format of its own output to feed to another assembler, you can't change the inline assembly, either.

how to integrate assembly code when i am designing a compiler in c?

i am designing a compiler in c . but for certain problems like big integers i have to code in assembly code . so how can i integrate assembly code in c?
i am wrting my code in dev cpp.. which i suppose uses gcc ... in windows..!!..
pls give me instructions for linux too
using asm
Good article : GCC-Inline-Assembly-HOWTO
Use the 'asm' instruction, e.g.
asm("movl %ecx %eax"); /* moves the contents of ecx to eax */
Don't you compile the runtime with your own compiler?
Note that another option is to use an external assembler (like AS). Less optimal, but the principle is portable. (though assembler syntaxes vary wildly)
Our own little compiler (which is GCC linking compatible) used AS for most of its assembler, and only acquired an own internal assembler after 8 year or so.
P.s. if you implement an internal assembler, have a look at NASM, their tables of assembler instructions and their addressing are really clean and can be often get converted (and used for regular updates for new instructions)

Resources