I want to call define a function in asm file and call this function from a Cpp file/function. Also I have to compile the project on 64-bit platform.
Please help me in doing that as I don't have much idea about assembly code. Any help will be appreciated.
Thanks
This file is an ASM file from ffdshow that performs some work with CPUID. It's both x64 and x86. YASM is used to assemble it.
What most people do today is not write ASM code but use intrinsic functions. There are intrinsic functions for all SSE/AVX/etc. even for low level ring0 instructions. Intrinsic functions allow the compiler to do extra optimizations and are shared between 32 and 64bit builds.
A code snippet would help, but if you want to place inline assembly within a regular C++ function, you can do that by placing it in an asm block like this:
void myClass::myFunc() {
// cpp code
int a = 0;
// ...
// asm code
__asm {
mov eax, ebx;
// ...
};
// more cpp code
// ...
}
Related
If I use the _byteswap_uint64() intrinsic of MSVC with the mostly MSVC compatible compiler clang-cl the code generates a call to the external library function _byteswap_uint64() which does the well known mask and shift orgy. Whith MSVC I simply get a x86 BSWAP instruction which is there since the 486 so there shouldn't be any processor optimization level relevant here. clang-cl understands a lot of command line options MSVC doesn't understand, even -march=native. So if I have -march=native the code is still a call to the mentioned function.
I use clang-cl 13 through the IDE (installed from the Visual Studio installer).
Is there a way to get proper code like with MSVC ?
I've got it. Simply use the clang specific intrinsics with conditional compilation:
#include <cstdint>
#include <intrin.h>
uint64_t swapThis( uint64_t value )
{
#if defined(__llvm__)
return __builtin_bswap64( value );
#elif defined(_MSC_VER)
return _byteswap_uint64( value );
#endif
}
clang_ isn't defined with clang-cl under Windows but only with clang++ under Windows, so I had to use _llvm.
I trying to port the vaiven virtual machine code to windows for learning purposes.
I compiled and tested the code on Linux. Most of the c++ code compiles fine with visual studio 2019 community edition.
There is one function that i don't know how to port it to windows. My guess is that this class allows to get the base of the stack frame.
class Stack {
uint64_t* rbp();
};
uint64_t* __attribute__ ((noinline)) vaiven::Stack::rbp() {
asm("mov (%rbp), %rax");
}
After googling about assembler using Intel notations I deduced that the equivalent code would be:
__declspec(noinline) uint64_t* vaiven::Stack::rbp() {
__asm
{
mov rax, DWORD PTR [rbp];
}
}
But I don't have any background in assembler coding. So I have two questions :
Is this translation to intel assembler correct ?
The Visual Studio community edition does not support inline
assembler for x64 targets. But it supports Intrinsics . Can we get the base of the stack frame in C/C++ code without writing assembler code in an external file
?
Thanks
I'm trying to port a program to x64 using vs2008. The problem is, however, that the is some inline asm code that is not supported on x64. This asm code is used to push arguments with unknown type or number to functions from dll. It is an interpeter based program in which you can specify a function to use from a certain dll and the program pushes the arguments and calles the function at compile time.
Using various sources I've concluded that generating seperate .asm files that contain asm functions which can be compiled unsing masm and their obj files linked to vs2008. Using different files for x86 and x64 the program builds for both problems. The problem is however, that the functions do not replicate what the inline asm is doing.
I converted the following inline code, for example:
double a = Evaluate(arg[i]).num;
_asm push a + 4
_asm push a
j += 8;
To:
double a = Evaluate(arg[i]).num;
EvaluateFuncArgFloat(a);
j += 8;
With the follwoing .asm file:
TITLE EvaluateFuncArgFloat (evaluate_asm.asm)
.386
.model flat, C
.code
EvaluateFuncArgFloat PROC a:DWORD
push a + 4
push a
ret
EvaluateFuncArgFloat ENDP
END
This does not do what I'm expecting. The double simply does not end up in the function as it did when using inline asm.
My guess is that there is a small error or something I've left out, but after many tries I can't seem to get it to work. Hopefully someone can help me with this problem, it is very much appriciated.
A sneaky way to do this could be
EvaluateFuncArgFloat PROC a:DWORD
pop eax ;ret address popped to a safe register (if not ax/eax)
push a + 4
push a
push eax ;ret address back at top of stack
ret
EvaluateFuncArgFloat ENDP
The problem is you've pushed 2 numbers onto the stack and not removed them a+4 and a
Presumably another part of your original code deals with this in the original program
I am making SYSTEM CALL for linux 2.6.39 kernel.
I have completed all the edits in the files. Now When i am trying to compile the kernel it is showing this error :
error: stdio.h: No such file or directory
If i remove stdio.h, Will the system call work ???
My code is
#include<stdio.h>
#include <linux/linkage.h>
asmlinkage long sys_atvfcfs(int at[], int bt[], int n)
{
int i=0;
int j,t,wt[n],sum,q;
float avgwt;
for(j=i+1;j<n;j++)
{
if(at[i]>at[j])
{
t=at[i];
at[i]=at[j];
at[j]=t;
q=bt[i];
bt[i]=bt[j];
bt[j]=q;
}
}
wt[0]=0;
sum=0;
for(i=0;i<n-1;i++)
{
wt[i+1]=wt[i]+bt[i];
sum=sum+(wt[i+1]-at[i]);
}
avgwt=sum/n;
return avgwt;
}
I have no idea what your system call is supposed to do, but it doesn't call any functions declared in stdio.h. (It doesn't call any functions at all, in fact.) So it should be safe to remove that line.
stdio.h is a C library header. It's available in ordinary C programs, but a kernel is different. A kernel is self-contained; it can't depend on userspace libraries, because userspace libraries depend on the kernel to do their work. Instead, the kernel has its own internal library of useful functions that you'll want to learn about if you're doing kernel development.
I do'nt see any io functions used in your code, so you don't need to include stdio.h
You don't need stdio.h in kernel programming. If you need to print something, use printk instead of printf.
I need to put markers to C++ code that should be visible in assembly or binary. It seems it’s straight forward to do it for 32 using inline assembly:
__asm {
NOP
NOP
NOP
}
or using DB assembly statement:
__asm {
DB 0x00, 0xFF, 0x10
}
But VisualStudio 2005 and better does not support inline assembly for x64. Is there any way to do it? Probably I can make a function in separate assembly module but how I can be sure that linker will put an actual assembly there instead of CALL?
Define a global volatile variable somewhere, say volatile __int64 blah = 0;. Then wherever you want some marker, use _InterlockedCompareExchange64(&blah, SOME_UNIQUE_CONSTANT1, SOME_UNIQUE_CONSTANT2);. You'll be guaranteed to find instructions loading ECX:EBX with SOME_UNIQUE_CONSTANT1 and EDX:EAX with SOME_UNIQUE_CONSTANT2 followed by LOCK CMPXCHG8B (0xF0, 0x0F, 0xC7, etc -- see instruction encoding details).
The MSDN says you can use intrinsic functions.
//MyAsmCode.asm
.code
MyFunction proc
...
MyFunction endp
end
compile it (ml64.exe).
You get object file (MS COFF 64): MyAsmCode.obj
In VS add MyAsmCode.obj to linker additional dep.
Now you can call this function. ;)