how to call assembly program inside c program- Visual studio 2010 - c

I need to call inline asm function in my c program "mainFunction.c"
#include<stdio.h>
#include<math.h>
double inline __declspec (naked) __fastcall sqrt14(double n)
{
_asm fld qword ptr [esp+4]
_asm fsqrt
_asm ret 8
}
int main(){
double a=10.5;
double b;
b=sqrt14(a);
return 0;
}
When I compile this program I am getting syntax errors.
error C2143: syntax error : missing ';' before '{'
error C2085: 'sqrt14' : not in formal parameter list
error C2054: expected '(' to follow 'inline'
if I change the file name to "mainFunction.cpp" means the program works fine.

You didn't specify which errors you got, but the function definition seems a little suspicious. See - http://msdn.microsoft.com/en-us/library/h5w10wxs.aspx
The compiler cannot generate an inline function for a function marked with the naked attribute, even if the function is also marked with the __forceinline keyword.
It also doesn't make a lot of sense to try stripping a function that's going to be inlined anyway, inlining already does most of the job for you.

Related

How to compile C functions that start with __asm in arm-none-eabi?

I'm trying to compile this PTPD code https://github.com/mpthompson/stm32_f4_ptpd . Unfortunately, it requires premium version of Keil. Therefore, I am migrating it to use arm-none-eabi and Makefile.
I have managed to get the rest of the program to compile, except for https://github.com/mpthompson/stm32_f4_ptpd/blob/master/libraries/RTX-v4.73/SRC/ARM/HAL_CM4.c .
Example problem place:
__asm void rt_set_PSP (U32 stack) {
MSR PSP,R0
BX LR
}
This file fails with:
../libraries/rtx-v4.73/SRC/ARM/HAL_CM4.c:50:7: error: expected '(' before 'void'
__asm void rt_set_PSP (U32 stack) {
^~~~
../libraries/rtx-v4.73/SRC/ARM/HAL_CM4.c:72:20: error: stray '#' in program
LSLS R0,#31
It seems like it is related to the compiler (GNU compiler not supporting this syntax?) or some flags, but googling hasn't been fertile so far.

Behaviour of 2 inline functions calling each other in C

I am in the process of trying to learn C's more advanced aspects and wrote this when experimenting with the __inline__ keyword:
#include <stdio.h>
void f(int);
void g(int);
__inline__ void f(int egg)
{
printf("f %d\n", egg);
g(egg);
}
__inline__ void g(int egg)
{
printf("g %d\n", egg);
f(egg);
}
int main()
{
f(123);
return 0;
}
I went to the GNU manuals and found that the -Winline compiler option warns when a function marked __inline__ can't be substituted.
I was indeed expecting a warning, but I compiled this program with gcc -ansi -pedantic -Wall -Wextra -Winline -o test test.c and there were no warnings.
When I ran the program, it printed out the number a whole bunch of times before a segmentation fault, presumably due to the recursion limit being exceeded.
My question is, how does gcc behave in cases like that? If it does inline the functions, how does it know it hit a recursive call between two functions?
Thank you in advance
https://gcc.gnu.org/onlinedocs/gcc-7.4.0/gcc/Inline.html#Inline
GCC does not inline any functions when not optimizing unless you specify the ‘always_inline’ attribute for the function
Since you are compiling without optimization, gcc does not even try to inline your functions, hence you do not get a warning that it wasn't done.
When I compile your code with -O -Winline, I get a warning as expected:
inline.c: In function ‘main’:
inline.c:8:17: warning: inlining failed in call to ‘f’: call is unlikely and code size would grow [-Winline]
__inline__ void f(int egg)
^
inline.c:24:5: note: called from here
f(123);
^~~~~~
According to what I see in goldbolt this case the compiler is smart enough to understand that that code is equivalent to a endless loop (see .L2 in the code below).
This optimization is possible when recursive functions are tail recursive
This has nothing to do with __inline__. In fact if you remove the __inline__ keyword you get the same optimization and also the assembly code for g and f, which are never called.
.LC0:
.string "f %d\n"
.LC1:
.string "g %d\n"
main:
sub rsp, 8
.L2:
mov esi, 123
mov edi, OFFSET FLAT:.LC0
xor eax, eax
call printf
mov esi, 123
mov edi, OFFSET FLAT:.LC1
xor eax, eax
call printf
jmp .L2
The following compare the assembly generated by gcc with (on the right) and withtout (on the left) __inline__ keyword for g and f.
As you can see the main contains exactly the same code. The only difference is that you get additional code for g and f.

Does __asm{}; return the value of eax?

Simple question. The function asm in C is used to do inline assembly in your code. But what does it return? Is it the conventional eax, and if not, what does it return?
__asm__ itself does not return a value. C standard does not define how __asm__ should handle the return value, so the behavior might be different between compilers. You stated that Visual Studio example is valid, but Visual Studio uses __asm. __asm__ is used at least by GCC.
Visual Studio
To get the result in a C program, you can place return value to eax in the assembly code, and return from the function. The caller will receive contents of eax as the return value. This is supported even with optimization enabled, even if the compiler decides to inline the function containing the __asm{} block.
It avoids a store/reload you'd otherwise get from moving the value to a C variable in the asm and returning that C variable, because MSVC inline asm syntax doesn't support inputs/outputs in registers (except for this return-value case).
Visual Studio 2015 documentation:
int power2( int num, int power )
{
__asm
{
mov eax, num ; Get first argument
mov ecx, power ; Get second argument
shl eax, cl ; EAX = EAX * ( 2 to the power of CL )
}
// Return with result in EAX
// by falling off the end of a non-void function
}
clang -fasm-blocks supports the same inline-asm syntax but does not support falling off the end of a non-void function as returning the value that an asm{} block left in EAX/RAX. Beware of that if porting MSVC inline asm to clang. It will break horribly when compiled with optimization enabled (function inlining).
GCC
GCC inline assembly HOWTO does not contain a similar example. You can't use an implicit return as in Visual Studio, but fortunately you don't need to because GNU C inline asm syntax allows specifying outputs in registers. No hack is needed to avoid a store/reload of an output value.
The HOWTO shows that you can store the result to C variable inside the assembly block, and return value of that variable after the assembly block has ended. You can even use "=r"(var) to let the compiler pick its choice of register, in case EAX isn't the most convenient after inlining.
An example of an (inefficient) string copy function, returning value of dest:
static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__( "1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
: "0" (src),"1" (dest)
: "memory");
return dest;
}
(Note that dest isn't actually an output from the inline asm statement. The matching constraint for the dummy output operands tells the compiler the inline asm destroyed that copy of the variable so it needs to preserve it across the asm statement on its own somehow.)
If you omit a return statement in a non-void function with optimization enabled, you get a warning like warning: no return statement in function returning non-void [-Wreturn-type] and recent GCC/clang won't even emit a ret; it assumes this path of execution is never taken (because that would be UB). It doesn't matter whether or not the function contained an asm statement or not.
It's unlikely; per the C99 spec, under J3 Implementation-defined behaviour:
The asm keyword may be used to insert assembly language directly into
the translator output (6.8). The most common implementation is via a statement of the form:
asm ( character-string-literal );
So it's unlikely that an implementor is going to come up with an approach that both inserts the assembly language into the translator output and also generates some additional intermediary linking code to wire a particular register as a return result.
It's a keyword, not a function.
E.g. GCC uses "=r"-type constraint semantics to allow you in your assembly to have write access to a variable. But you ensure the result ends up in the right place.

Cmake compile __asm assembly inline code

I am trying to compile quake2 code which uses the __asm keyword like so:
__declspec( naked ) int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs,
struct cplane_s *p)
{
static int bops_initialized;
static int Ljmptab[8];
__asm {
push ebx
cmp bops_initialized, 1
je initialized
mov bops_initialized, 1
// more code...
I am using Clion which uses Cmake internally to compile. The thing is that in the code above I get the following errors
C:\Users\Shiro\ClionProjects\quake2\src\game\q_shared.c: In function
'BoxOnPlaneSide':
C:\Users\Shiro\ClionProjects\quake2\src\game\q_shared.c:423:8: error:
expected '(' before '{' token
__asm {
^
and the errors go on from there. So, how can I make this compile ? any changes to my CMakeLists.txt perhaps ? Here is part of what I have now
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Traditional -std=gnu89")

porting C compilation from MinGW to VisualStudio(nmake)

My current job at the university is to port a C program from MinGW (windows) to Visual Studio (nmake).
I have got a valid "makefile.vc" file for a very similar C program.
My approach was to adopt the Makefile (i.e. "makefile.vc") to the program I need to port.
All but four C files seem to compile fine. Those four files have various errors for example, syntax errors and "unknown size".
Should I continue with my approach to change the Makefile or use CMAKE instead of nmake?
Is there a tutorial or any other pointer on porting a C program from MinGW/gcc to nmake?
typedef struct {
A_TypeConverter *converter;
char *domain;
} enumeratorConverterEntry;
static enumeratorConverterEntry enumeratorConverterEntries[]; /* line 186 */
error:
f.c(186) : error C2133: 'enumeratorConverterEntries' : unknown size
typedef struct AsmInstructionInfo {
int flags;
CONST char **argTypes; /* line 7 */
int minArgs;
int maxArgs;
int cArgs;
} AsmInstructionInfo;
error:
fAssemble.c(7) : error C2061: syntax error : identifier 'CONST'
..
/* file fStack.c: */
#ifdef CHECK_ACTIVATION_COUNTS
/* code */
#endif
/* more code */
void fShowStack(l_Interp *interp) { /* line 94 */
l_CallFrame *framePtr;
/* more code */
error:
fStack.c(94) : error C2143: syntax error : missing ')' before '*'
fStack.c(94) : error C2143: syntax error : missing '{' before '*'
fStack.c(94) : error C2059: syntax error : ')'
fStack.c(94) : error C2054: expected '(' to follow 'interp'
static enumeratorConverterEntry enumeratorConverterEntries[]; /* line 186 */
That looks like a valid incomplete, forward declaration of an array, which would be valid syntax, except I think for the static qualifier. I don't have a copy of the 'C' standard in front of me, but reading between the lines on the results of Googling "forward declaration of static array" seems to indicate that an incomplete definition of a static array results in undefined behavior, so Microsoft and GNU are legitimately entitled to do whatever they want with it. GNU accepts it, and Microsoft rejects it. As Mark Wilkins points out you should be make the Microsoft compiler happy by replacing it with:
extern enumeratorConverterEntry enumeratorConverterEntries[]; /* line 186 */
In general it's worth noting that the Microsoft compiler only supports the C89 standard, while the GNU compiler supports portions of the C99 standard, and several of their own extensions, depending on the arguments to the compiler.
The errors in fAssemble.c and fStack.c look like one or more preprocessor files are missing or incomplete. You should search your source to find out where CONST and l_Interp are defined, and then figure out why they are not being picked up in the files where the errors are occurring.
I just now tried out that array declaration with MinGW, and it does compile. To make it link, though, it needs the array to be defined elsewhere. The result is that it appears to be the same as the extern storage class:
extern enumeratorConverterEntry enumeratorConverterEntries[];
I'm not sure if there are other subtleties associated with the original declaration using a static storage class for the global.

Resources