Equivalent for NOP in C for Embedded? - c

I use KEIL to compile a program.
The program uses the code
asm("NOP");
Unfortunately KEIL compiler does not accept the statement.
The idea is to introduce a delay by using NOP (no operation) assembly code.
What is the actual equivalent of this in C ? Does this vary with the embedded controller that I use?

There's an intrinsic nop in most compilers, Keil should have this as well - try __nop()
See - https://www.keil.com/support/man/docs/armcc/armcc_chr1359124998347.htm
Intrinsic functions are usually safer than directly adding assembly code for compatibility reasons.

Does this vary with the embedded controller that I use?
Yes. Inline assembly is not part of the C standard (yet), it varies from compiler to compiler and sometimes even between different target architectures of the same compiler. See Is inline asm part of the ANSI C standard? for more information.
For example, for the C51 Keil compiler, the syntax for inline assembly is
...
#pragma asm
NOP
#pragma endasm
...
while for ARM, the syntax is something like
...
__asm {
NOP
}
...
You will need to check the manual for the actual compiler you are using.
For some of the more common opcodes, some compilers provide so-called intrinsics - these can be called like a C function but essentially insert assembly code, like _nop_ ().

If you are using Keil for ARM Cortex target (e.g. stm32), you are most probably also using CMSIS library. It has portable macros and inline functions for all assembly instructions written like this: __NOP().

Related

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.

Is `__asm nop` the Windows equivalent of `asm volatile("nop");` from GCC compiler

In Windows, can __asm nop be swapped for asm volatile("nop"); (used in GCC compiler) and yield the same result?
I have read that volatile() (in GCC) guarantees the call will not be optimized away. However, it doesn't port directly to Windows, and I was curious if it can simply be removed or if it needs to be replaced with a similar construct.
The __asm keyword implementation is quite simplistic in MSVC. It always emits the machine code unaltered and the optimizer doesn't touch it. Nor does it make any assumptions about machine state after the __asm, that has a knack for defeating other optimizations.
So, no, nothing similar to volatile() is required, it can't disappear. Plain __asm { nop } will always survive unscathed and is equivalent to the GCC assembly.
Do keep in mind that inline assembly is not a good long-term strategy, support for it was removed completely in the x64 compiler and is pretty unlikely to ever come back. You'll have to fall back to intrinsics or link code written in assembly and compiled with, say, ml64.exe. That does defeat NOP injection, but code alignment is already well taken care of by the optimizer and doesn't need help. Also the reason you probably should not do this at all.
For the Microsoft compiler, use the __nop() intrinsic function to emit a nop instruction without handicapping the compiler's optimizer. This would also be cross-platform across all Windows targets (32 bit ARM V7, 64 bit ARM V8, IA32, X64).

Hardware square root gcc

I'm trying to use the hardware instructions to compute some mathematical functions. For example the square root (sqrtpd instruction). I'm compiling my C code with GCC.
Does Anybody know what are the gcc options to force to compile with the hardware instructions and not to use the libc? Or if I need to do something special on my source code? (Without writing asm code).
On gcc you should use __builtin_ia32_sqrtpd.
The easiest way is to use optimization flags. -O1 generates
sqrtsd %xmm1, %xmm0
in assembly code. Try using -S flag with gcc to generate assembly and look how optimization flags works.
Why don't you just write the desired hardware instruction in assembly code directly.
As far as I know, writing assembly code directly in c code is possible. It is called Inline Assembly. [ See here: http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html ]

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

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