Not mine, I just came across it while googling.
Machine instructions are put inside a string literal. Said literal is then casted to a function pointer to be called. Pretty exotic, what do you think?
http://stackoverflow.com/a/5602143
Posted 01 March 2013 - 07:42 PM
Not mine, I just came across it while googling.
Machine instructions are put inside a string literal. Said literal is then casted to a function pointer to be called. Pretty exotic, what do you think?
http://stackoverflow.com/a/5602143
Posted 01 March 2013 - 09:29 PM
Nice hack, though it won't usually work nowadays because instructions outside code segments will not be run by the operating system. You could also just use a char array as { 0xC3, 0xDD, ... } instead of using a string literal with escape codes.
Also, you're fired ![]()
Posted 02 March 2013 - 03:53 AM
Posted 02 March 2013 - 04:33 AM
Edited by Khatharr, 02 March 2013 - 04:34 AM.
Posted 15 March 2013 - 09:10 AM
If you want to do runtime x86 and x86_64 code generation properly (and yes, there's use cases for it), I would recommend using Xbyak. Nice little C++ DSL to generate machine code at runtime, complete with labels, jumping to them and all sorts of nice stuff.
Posted 15 March 2013 - 12:54 PM
Current Status / Downloads: http://cr88192.dyndns.org:8080/wiki/index.php/BGB_Current_Status
YouTube Channel: http://www.youtube.com/user/BGBTech
Main Page: http://cr88192.dyndns.org:8080/wiki/index.php/Main_Page
Forums: http://cr88192.dyndns.org:8080/phpBB3
Posted 15 March 2013 - 01:58 PM
Posted 15 March 2013 - 02:19 PM
I've never personally tested this, but http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553%28v=vs.85%29.aspx indicates that VirtualAlloc or VirtualProtect with the appropriate PAGE_EXECUTE flag should allow it.
It's still horrible though. Even if there are sometimes reasons why you may want to do it, it remains horrible (just imagine trying to debug it!)
It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.
Posted 15 March 2013 - 02:38 PM
Posted 15 March 2013 - 03:33 PM
yep, I didn't know about LLVM when I wrote mine, and when I encountered it didn't want to have to go through the hassle of converting all my stuff over to work with it.LLVM's JIT engine is pretty much the definitive kick-ass explosion-laden version of this concept :-)
Current Status / Downloads: http://cr88192.dyndns.org:8080/wiki/index.php/BGB_Current_Status
YouTube Channel: http://www.youtube.com/user/BGBTech
Main Page: http://cr88192.dyndns.org:8080/wiki/index.php/Main_Page
Forums: http://cr88192.dyndns.org:8080/phpBB3
Posted 15 March 2013 - 08:21 PM
Yeah. I was expecting to have to use those functions when I was goofing with it. The VS 2008 debugger had no problem jumping right into the code though. In disassembled view, ofc. It is pretty horrible though.mhagain, on 15 Mar 2013 - 13:26, said:
I've never personally tested this, but http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553(v=vs.85).aspx indicates that VirtualAlloc or VirtualProtect with the appropriate PAGE_EXECUTE flag should allow it.
It's still horrible though. Even if there are sometimes reasons why you may want to do it, it remains horrible (just imagine trying to debug it!)
Posted 16 March 2013 - 01:08 AM
IIRC, DEP is not enabled by default for user code with 32-bit apps, so you can generally get around needing it.
Yeah. I was expecting to have to use those functions when I was goofing with it. The VS 2008 debugger had no problem jumping right into the code though. In disassembled view, ofc. It is pretty horrible though.mhagain, on 15 Mar 2013 - 13:26, said:
I've never personally tested this, but http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553(v=vs.85).aspx indicates that VirtualAlloc or VirtualProtect with the appropriate PAGE_EXECUTE flag should allow it.
It's still horrible though. Even if there are sometimes reasons why you may want to do it, it remains horrible (just imagine trying to debug it!)
Current Status / Downloads: http://cr88192.dyndns.org:8080/wiki/index.php/BGB_Current_Status
YouTube Channel: http://www.youtube.com/user/BGBTech
Main Page: http://cr88192.dyndns.org:8080/wiki/index.php/Main_Page
Forums: http://cr88192.dyndns.org:8080/phpBB3
Posted 16 March 2013 - 01:24 PM
Is RX even used? I remember that with protected mode you could set a selector to be unreadable and unwritable but executable (meaning you can get the CPU run code off it, but you can't get its instructions to read memory from that area), I'd imagine this is still possible in long mode.
Posted 16 March 2013 - 07:04 PM
it is basically the same as before just with the addition of an NX/XD bit to disable executing code.Is RX even used? I remember that with protected mode you could set a selector to be unreadable and unwritable but executable (meaning you can get the CPU run code off it, but you can't get its instructions to read memory from that area), I'd imagine this is still possible in long mode.
Edited by cr88192, 16 March 2013 - 07:04 PM.
Current Status / Downloads: http://cr88192.dyndns.org:8080/wiki/index.php/BGB_Current_Status
YouTube Channel: http://www.youtube.com/user/BGBTech
Main Page: http://cr88192.dyndns.org:8080/wiki/index.php/Main_Page
Forums: http://cr88192.dyndns.org:8080/phpBB3
Posted 21 March 2013 - 10:37 PM
lol, I was literally thinking about creating a thread about this a few minutes ago: writing assembly code without an inline assembler!!!
I've done this many times, but I've never actually used a string. I always used an dynamically allocated array of bytes defining my assembly code. I've never had to do this for a game (except once when I first started coding for MacOSX and I didn't know what Apple's breakpoint function was called), but I've done this very frequently when working on emulators. Not trying to brag, but some of you might actually recognize my nickname. If you do, then I guess I don't need further explanation.
It really comes in handy if you're writing a static-rec or dynarec engine (I prefer static rec).
For games, I'd only use it to write my own intrinsics for something like SSE, CPUID or those oddball instructions that aren't recognized by the inline assembler. Of course, this isn't an easy task, you'll have to read the docs on Intel's webpage: http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
WBINVD anyone? ![]()
Oh, and depending on what compiler you're using, debugging it isn't hard! XCode disassembles properly written byte encoded assembly code and steps through it normally. That's just one of the many reasons I absolutely LOVE XCode and MacOSX! ![]()
Shogun
Posted 22 March 2013 - 03:07 AM
@Shogun: yes, this is also a possible reason to write an assembler.
then you can dynamically assembler whatever, without having to manually invoke the Intel docs and generate the machine code sequences by hand.
also, in the simple case, writing an assembler isn't really hard, in my case most of the "work" was the long/tedious job of transcribing the instruction-listings and similar.
(initially, I wrote it over the course of a few days, but the assembler has expanded a bit since then).
though, yes, I have still used manually-generated machine code in a few places, as for certain uses this is more useful (the assembler isn't entirely free...).
as an example, from my listing:
add 04,ib al,i8 X80/0,ib rm8,i8 aleph WX83/0,ib rm16,i8 aleph TX83/0,ib rm32,i8 aleph X83/0,ib rm64,i8 X02/r r8,rm8 aleph X00/r rm8,r8 aleph W05,iw ax,i16 WX81/0,iw rm16,i16 aleph WX03/r r16,rm16 aleph WX01/r rm16,r16 aleph T05,id eax,i32 TX81/0,id rm32,i32 aleph TX01/r rm32,r32 aleph TX03/r r32,rm32 aleph X05,id rax,i32 X81/0,id rm64,i32 X03/r r64,rm64 X01/r rm64,r64 ... inc W40|r r16 leg T40|r r32 leg XFE/0 rm8 aleph WXFF/0 rm16 aleph TXFF/0 rm32 aleph XFF/0 rm64
where 'X' basically means where to put the REX prefix, W/T where to insert the operand-size prefix (when relevant), ...
(other letters have other meanings, like V/S for address-size prefix, H/I/J/K/L for VEX and XOP forms, ...).
likewise: '/r' means "insert ModRM here", ',id' means immediate dword, ...
and the last line is basically for flags, such as to indicate when/where sequences are valid (CPU modes, ...).
'leg', basically means "legacy only", 'long' means long-mode only, and 'aleph' was basically for a past x86 subset.
I had once considered having a verifiable x86 subset sort of like NaCl (but more like the JVM verifier), but this idea didn't really go anywhere.
when the assembler is compiled, a tool basically takes the instruction listings, and converts them into the relevant C source files and headers (basically, it converts them into big prebuilt tables).
Edited by cr88192, 22 March 2013 - 03:08 AM.
Current Status / Downloads: http://cr88192.dyndns.org:8080/wiki/index.php/BGB_Current_Status
YouTube Channel: http://www.youtube.com/user/BGBTech
Main Page: http://cr88192.dyndns.org:8080/wiki/index.php/Main_Page
Forums: http://cr88192.dyndns.org:8080/phpBB3