I'm having a problem using inline assembly. Here is my code, it's a fairly simple wrapper:
void __declspec(naked) __fastcall CatchWrapper()
{
static const DWORD Continue = 0x6facc128;
static const DWORD NoContinue = 0x6facc089;
__asm
{
push ecx
call CommandCatcher
test eax,eax
je NoContinue
jmp Continue
}
}the line "je NoContinue" is failing to compile with the message "Improper operand type".
Quotec:\Documents and Settings\Ron\My Documents\Visual Studio Projects\Plugin\Catcher.cpp(15): error C2415: improper operand type
If I switch the je to a jz, jne, or jnz, there is no change. If I switch it to a jmp, it works fine (compiles, I mean). Any idea why the compiler doesn't like je and jne?
As far as I know, conditional jumps are always relative jumps. The opcode has an 8-bit or 32-bit signed jump offset. There's just no support in the cpu for reading the destination from a memory location. To find out more about this, look at "addressing modes" for various instructions.
Hmm, that would make it rather difficult to do a conditional jump to a specific address. How would you get around it?
I'm thinking like this:
void __declspec(naked) __fastcall CatchWrapper()
{
static const DWORD Continue = 0x6facc128;
static const DWORD NoContinue = 0x6facc089;
__asm
{
push ecx
call CommandCatcher
test eax,eax
je bah
jmp Continue
bah:
jmp NoContinue
}
}
Is that the best way to do it?
If I was a compiler, I might do something like this:
void __declspec(naked) __fastcall CatchWrapper()
{
#define Continue 0x6facc128
#define NoContinue 0x6facc089
__asm
{
push ecx
call CommandCatcher
test eax, eax
sbb eax, eax
and eax, Continue-NoContinue
add eax, NoContinue
jmp eax
}
}
The code is completely untested, but you get the idea?
haha that's really cool code, honestly.
I get the idea, make eax a boolean, use overflow and whatnot.. that's nuts, but I love the code :D
That's pretty common, try for example:
int x = somebool ? 17 : 42;
Or almost anything else with the ?: operator, and see how the compiler compiles it. Microsoft's compiler likes to turn that into a test+sbb+and+add combination.
Actually, later that same day I demonstrated that fact with this code:
typedef void somefuncptr(void);
#define address1 0x12345678
#define address2 0x9abcdef0
((somefuncptr*)(yourfunctionyoucall() ? address1 : address2)) ();
which becomes
00009 e8 00 00 00 00 call ?yourfunctionyoucall@@YAHXZ ; yourfunctionyoucall
0000e f7 d8 neg eax
00010 1b c0 sbb eax, eax
00012 25 88 77 77 77 and eax, 2004318088 ; 77777788H
00017 05 f0 de bc 9a add eax, -1698898192 ; 9abcdef0H
0001c ff d0 call eax
It is common for compilers to generate that code, but not nearly as common for human assembler coders to do. That's why I said "if i was a compiler" :)
<ot>
If you squint, it looks like Adron's code is trying to spell something ... "IRb --"
</ot>