473,788 Members | 2,811 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

compiling assembler just in time and jumping to the result from a c++ program

Mostly for testing reasons I'd like to see if it makes sense to chose
the following approach for just-in-time compilation of shaders for a
renderer:
Seeing as the shaders themsefs consist mostly of very basic operations
I'd like to translate them into assembly, have an assembler compile the
binary code and then call the resulting machine code from c++.

The thing is that up until now I have only used inline assembly in my
c++ projects, so there's a few things I hardly know anything about and
would be very greatful if anyone here could point me in the right
direction:
- Having a set of asm instructions, say "addl 5, %%eax" or "add eax, 5"
respectively, how would I go about translating just this one line into
binary? (in a way that doesn't mean i'll have to re-write the whole
thing when porting to a different os if at all possible :)
- How do I jump into the binary from my c++ app in a way that I can jmp
back at the end of my assembly code segment?

Thanks!

Dec 23 '06 #1
14 2479
sp******@crayne .org napsal:
Mostly for testing reasons I'd like to see if it makes sense to chose
the following approach for just-in-time compilation of shaders for a
renderer:
Seeing as the shaders themsefs consist mostly of very basic operations
I'd like to translate them into assembly, have an assembler compile the
binary code and then call the resulting machine code from c++.

The thing is that up until now I have only used inline assembly in my
c++ projects, so there's a few things I hardly know anything about and
would be very greatful if anyone here could point me in the right
direction:
- Having a set of asm instructions, say "addl 5, %%eax" or "add eax, 5"
respectively, how would I go about translating just this one line into
binary? (in a way that doesn't mean i'll have to re-write the whole
thing when porting to a different os if at all possible :)
- How do I jump into the binary from my c++ app in a way that I can jmp
back at the end of my assembly code segment?

Thanks!
In real operating system you usually cannot simply create some data in
memory and then say "It's my routine, jump there" (It could work in
DOS, but who cares about DOS now...).

There is no standard C++ solution for this. But you can do it this way:
- generate your assembler (or C, C++, it does not matter) source into
some file
- compile it with your favourite compiler
- link it into dynamic library
- load this library into memory, resolve symbols and call your function

For compilation you need start a new process. Starting processes from
your program is non-portable. Use fork and exec (or execl or similar)
on POSIX systems or CreateProcess in Windows.

Loading dynamic library is also non standard from C++ point of view.
However it is standardized on POSIX platforms with dlopen family and on
Windows platform with LoadLibrary. Functions have very simillar API, it
may be simply #ifdef'ed.

Instead of #ifdefs you can use some library which hides platform
specific issues (like ACE, wxWidgets or anything else) which implements
starting processes and loading library.

Dec 23 '06 #2
Ondra Holub wrote:
In real operating system you usually cannot simply create some data in
memory and then say "It's my routine, jump there" (It could work in
DOS, but who cares about DOS now...).
I'm not sure what "real operating system" you had in mind, but in
Windows you most certainly *can* write machine code directly into
memory 'on the fly' and execute it there immediately. That's how the
assembler in BBC BASIC for Windows works, and without that capability
the language would be severely crippled! Some modern processors can be
set to prevent code execution in 'data' memory, but it's not the norm
in 32-bit Windows.

Richard.
Author of BBC BASIC for Windows.
http://www.rtrussell.co.uk/

Dec 23 '06 #3
- Having a set of asm instructions, say "addl 5, %%eax" or "add eax, 5"
respectively, how would I go about translating just this one line into
binary?
Look for a solution that does this already. It's probably something
commercial. Google is your friend.

Who knows, maybe someone has written an x86 compiler for free, in pure
C++ code. Writing compilers isn't hard at all actually, as long as you
stick to minimal implementation and implement the 1% of the features
that is used 99% of the time ;) Writing an asm compiler should be
really easy to do yourself actually. Just pick up an x86 manual and
away you go.
(in a way that doesn't mean i'll have to re-write the whole
thing when porting to a different os if at all possible :)
Assuming the OS is still on the same processor... shouldn't be a
problem I imagine! Getting the compiler on both OSs will be a different
matter, though.
- How do I jump into the binary from my c++ app in a way that I can jmp
back at the end of my assembly code segment?
No idea sorry. The answer should be simple though.

Dec 24 '06 #4
"Ondra Holub" <sp******@crayn e.orgwrites:
sp******@crayne .org napsal:
>Mostly for testing reasons I'd like to see if it makes sense to chose
the following approach for just-in-time compilation of shaders for a
renderer:
Seeing as the shaders themsefs consist mostly of very basic operations
I'd like to translate them into assembly, have an assembler compile the
binary code and then call the resulting machine code from c++.

The thing is that up until now I have only used inline assembly in my
c++ projects, so there's a few things I hardly know anything about and
would be very greatful if anyone here could point me in the right
direction:
- Having a set of asm instructions, say "addl 5, %%eax" or "add eax, 5"
respectively , how would I go about translating just this one line into
binary? (in a way that doesn't mean i'll have to re-write the whole
thing when porting to a different os if at all possible :)
- How do I jump into the binary from my c++ app in a way that I can jmp
back at the end of my assembly code segment?

Thanks!

In real operating system you usually cannot simply create some data in
memory and then say "It's my routine, jump there" (It could work in
DOS, but who cares about DOS now...).
Well, the problem is not only the OS. The OS could indeed prevent
execution from data pages, but you can usually get some memory page
with both the write and execute access rights.

The other difficulty is that modern processors have distinct
instruction and data caches. So once you've written the code to the
data block, the code can still be in the data cache when you try to
load it in the instruction cache, and you won't get it, but what was
stored previously. So you need to flush the instruction cache
everytime you've created a new function.

There is no standard C++ solution for this. But you can do it this way:
- generate your assembler (or C, C++, it does not matter) source into
some file
- compile it with your favourite compiler
- link it into dynamic library
- load this library into memory, resolve symbols and call your function
This is the standard way. If you don't want to be processor specific,
it's a good idea to go thru the program who knows what bytes the
current processor likes.

For compilation you need start a new process. Starting processes from
your program is non-portable. Use fork and exec (or execl or similar)
on POSIX systems or CreateProcess in Windows.
Isn't MS-Windows a POSIX system?

Loading dynamic library is also non standard from C++ point of view.
However it is standardized on POSIX platforms with dlopen family and on
Windows platform with LoadLibrary. Functions have very simillar API, it
may be simply #ifdef'ed.

Instead of #ifdefs you can use some library which hides platform
specific issues (like ACE, wxWidgets or anything else) which implements
starting processes and loading library.
Why are you bothering with MS-Windows anyways?
--
__Pascal Bourguignon__ http://www.informatimago.com/

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.

Dec 24 '06 #5
In article <11************ **********@a3g2 000cwd.googlegr oups.com>
sp******@crayne .org "ne**@rtrussell .co.uk" writes:
Ondra Holub wrote:
In real operating system you usually cannot simply create some data in
memory and then say "It's my routine, jump there" (It could work in
DOS, but who cares about DOS now...).
Mamy more programmers than you think, I suspect. Not all devices
and applications require GB of memory or to be network-aware.
Horses for courses...
I'm not sure what "real operating system" you had in mind, but in
Windows you most certainly *can* write machine code directly into
memory 'on the fly' and execute it there immediately.
As malware creators are abundantly aware :( The sad part is that
most such PCs (are they "personal anymore?) are connected to the
Internet -- a hostile environment where big bucks are concerned.
That's how the
assembler in BBC BASIC for Windows works, and without that capability
the language would be severely crippled! Some modern processors can be
set to prevent code execution in 'data' memory, but it's not the norm
in 32-bit Windows.
One man's meats, another man's poison... Anything that is really
good/useful can be subverted for nefarious usage, sadly.
Richard.
Author of BBC BASIC for Windows.
http://www.rtrussell.co.uk/
Pete
--
"We have not inherited the earth from our ancestors,
we have borrowed it from our descendants."

Dec 24 '06 #6
Isn't MS-Windows a POSIX system?
Well, there may be installed some POSIX layer (or Windows Services for
UNIX in Windows XP or 2003), but I am not sure that you get POSIX
functions in your C/C++ libraries (I do not mean cygwin or simillar).
Maybe it works, I do not have any experiences.

Dec 24 '06 #7
Pascal Bourguignon wrote:
The other difficulty is that modern processors have distinct
instruction and data caches. So once you've written the code to the
data block, the code can still be in the data cache when you try to
load it in the instruction cache, and you won't get it, but what was
stored previously. So you need to flush the instruction cache
everytime you've created a new function.
Not usually you don't. In Intel processors at least, and I would be
very surprised if AMD are any different, great care is taken to ensure
that self-modifying-code works correctly (since it is so prevalent).
There can certainly be a very significant performance hit (typically
because a data write may invalidate the code cache, causing a re-fetch)
but there is definitely no need for the programmer to take special
action of the sort you describe in the case of the IA-32 architecture.

Quoting from the Intel Optimization Manual: "Self-modifying code (SMC)
that ran correctly on Pentium III processors and prior implementations
will run correctly on subsequent implementations , including Pentium 4
and Intel Xeon processors":

http://developer.intel.com/design/Pe...als/245127.htm

Richard.
http://www.rtrussell.co.uk/

Dec 24 '06 #8
ne**@rtrussell. co.uk wrote:
I'm not sure what "real operating system" you had in mind, but in
Windows you most certainly *can* write machine code directly into
memory 'on the fly' and execute it there immediately. That's how the
assembler in BBC BASIC for Windows works, and without that capability
the language would be severely crippled! Some modern processors can be
set to prevent code execution in 'data' memory, but it's not the norm
in 32-bit Windows.
I believe in fact it is set to prevent such, but the trap handler does
"what you want" (for suitable choice of what to want...) by flushing
the cache and changing the pages from R/W data to read-only code.
It might get really expensive if the code wrote to its own page.

Dec 24 '06 #9
Robert Mabee wrote:
I believe in fact it is set to prevent such, but the trap handler does
"what you want" (for suitable choice of what to want...) by flushing
the cache and changing the pages from R/W data to read-only code.
Your evidence for that is what exactly? I'm pretty sure it's not the
case.
It might get really expensive if the code wrote to its own page.
Which of course is exactly what self-modifying code does. Yes it's
expensive in performance, but IA-32 processors support it without any
intervention from the OS (see my quote from the Intel Optimization
Manual elsewhere in this thread).

Richard.
http://www.rtrussell.co.uk/

Dec 24 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
5123
by: Steven T. Hatton | last post by:
Is there anything that gives a good description of how source code is converted into a translation unit, then object code, and then linked. I'm particularly interested in understanding why putting normal functions in header files results in multiple definition errors even when include guards are used. -- STH Hatton's Law: "There is only One inviolable Law" KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com Mozilla:...
9
2416
by: cppaddict | last post by:
Let's say you want to implement a Dictionary class, which contains a vector of DictionaryEntry. Assume each DictionaryEntry has two members, a word and a definition. Now assume your program needs to create a Dictionary *object* to be populated with values that come from a text file with a format like this: <dict.txt>
21
2051
by: Morten Aune Lyrstad | last post by:
I wish to create my own assembly language for script. For now it is mostly for fun and for the sake of the learning, but I am also creating a game engine where I want this system in. Once the assembler is done I will develop a simple script language/compiler which uses this assembler. What operators do you suggest I implement in it? Yours, Morten Aune Lyrstad
3
2479
by: H. S. | last post by:
Hi, I am trying to compile these set of C++ files and trying out class inheritence and function pointers. Can anybody shed some light why my compiler is not compiling them and where I am going wrong? I am using g++ (GCC) 3.3.5 on a Debian Sarge system. The compiler complains: //**************************** //**************************** Compiler output starts *********** cd /home/red/tmp/testprogs/
3
1579
by: enfis.the.paladin | last post by:
Hi to all! I have something like this: class FWrap { public: virtual void READ (void) = 0; } class Optimized { private:
2
1282
by: mclagett | last post by:
Can anyone please help me figure out why all of a sudden (even after many restarts of Visual Studio 2005 and reboots, etc) I am no longer able to set breakpoints in the disassembler window. I should mention that this is assembler code I generate by writing opcodes to memory, but for a month or so I had no problems. All of a sudden it stopped working. Is there some setting somewhere that has gotten set somehow, or did a security download...
2
2017
by: Jan Althaus | last post by:
Mostly for testing reasons I'd like to see if it makes sense to chose the following approach for just-in-time compilation of shaders for a renderer: Seeing as the shaders themsefs consist mostly of very basic operations I'd like to translate them into assembly, have an assembler compile the binary code and then call the resulting machine code from c++. The thing is that up until now I have only used inline assembly in my c++ projects,...
3
2061
by: Randy Yates | last post by:
Hi Folks, I have a cross-development problem in which I'm using the x86_64 version of Fedora Core 6 as a development system but want to build executables that are 32-bit. I've got a mix of C (mainly C) and about 2 or 3 assembly routines. I'm using yasm as my assembler and gcc 4.1.2 for my C compiler, and GNU ld version 2.17.50.0.6-2.fc6 20061020 as my linker. I thought that if I just specified a 32-bit target for the C compiler via...
13
2188
by: Analizer1 | last post by:
Hello all I have a idea...and dont know if it is possible...... we have a pretty huge system at work and we send EDI Special formatted Data to Several Other Companies, via sFtp,dial up, vpn depending on these customers requirements one of the areas we are using a implimentation in vb6 (yuck) but works...slow as well u know,
0
9498
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10370
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10113
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8995
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7519
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6750
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5538
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3677
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2896
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.