1

I am developing a C++ library that requires some external assembly functions to be included.

Currently, the C/C++ functions are being declared this way (generic format, not the exact code):

#if defined _WIN32
   #define DLL_ENTITY __declspec(dllexport)
#endif

#if defined _WIN32
   DLL_ENTITY
#endif
int Function (int argument);

and compile it (using a Makefile) with GCC using the -fPIC flag to create relocatable code that can be used from the programs linked to my library. For example (one command output of my Makefile):

g++ -I`pwd`/.. -Wall -fPIC -march=x86-64 -mtune=generic -g -c sort.cpp

and in Windows I create and configure a project with executable format DLL option in Visual Studio, then it does all the job.

Okay, my assembly functions look like this:

global function
global _function
function:
_function:
      ENTER reserved_bytes,nest_level
      ; ...get possible parameters...
      ; ...do something...
      LEAVE
      ret

Well, according to the NASM manual, for the Windows DLL libraries I must add something like:

export function

My doubts are these:

1) For Linux it does not mention nothing about 'export', I guess it is the same way as the C/C++ function/class prototypes that do not require any special treatment, they are declared in the same way as in standalone programs. Is it right? Just use 'export' for Windows and nothing for Linux?

2) What about the relocatable code generation? For Windows, the 'export' keyword makes it relocatable or JUST EXPORTABLE? And for Linux, do I need to use some flag equivalent to -fPIC or I must create the relocatable code by using BASED addressing? For example:

  add WORD[BP+myNumber],10h

     instead of

  add WORD[myNumber],10h

but in this case, how can I find the base address of the function to set BP (EBP/RBP) to it (just in case that I require to access LOCAL variables or data)?

David Z
  • 128,184
  • 27
  • 255
  • 279
kanito73
  • 87
  • 4
  • 1
    Easiest way: Write inline assembly. Otherwise: Good luck on dealing with ASLR on modern platforms. – Swordfish Feb 17 '19 at 04:32
  • 1
    DLLs and ELF shared libraries work differently in terms of how symbols get resolved, this is why exporting symbols is necessary on Windows and not on Linux. It has nothing to do with whether your code is relocatable or not. In order for your code to be relocatable you need to avoid having any absolute references in your assembly code. Using inline assembly doesn't fundamentally change this so I wouldn't recommend using it. On the other hand if you can avoid writing assembly altogether by using intrinsics, or even just plain C/C++ code, you should do that instead. – Ross Ridge Feb 17 '19 at 05:24
  • Hello Ross, thanks for your comment, last night I was able to build and test the Linux library, it works, now it is pending the Windows version. There are two important points:1) The same code MUST compile for both Linux and Windows (currently it does), and 2) I can't use native C/C++ because there are no equivalent instructions and emulating something similar with C++ would take a lot more instructions than a single ASM instruction, the idea of using assembly is to save processor cycles since such operations may be executed 10,000 or 100,000 or 1,000,000 times frequently – kanito73 Feb 17 '19 at 16:10
  • That would suggest you should be using intrinsics: https://learn.microsoft.com/en-us/cpp/intrinsics/x64-amd64-intrinsics-list?view=vs-2017 The ones starting with `_mm` are portable between Microsoft C++ and GCC, and most of the rest should have an equivalent function with a different name that GCC supports. I should also point out that the fact that you're using the ENTER instruction in your example code suggests that plain C/C++ code may in fact be faster than the assembly code you've written. https://stackoverflow.com/questions/26323215 – Ross Ridge Feb 17 '19 at 19:52

0 Answers0