Author | Message | Time |
---|---|---|
iago | I'm having a problem using inline assembly. Here is my code, it's a fairly simple wrapper: [code]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 } }[/code] the line "je NoContinue" is failing to compile with the message "Improper operand type". [quote]c:\Documents and Settings\Ron\My Documents\Visual Studio Projects\Plugin\Catcher.cpp(15): error C2415: improper operand type[/quote] 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? | August 6, 2003, 12:15 PM |
Adron | 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. | August 6, 2003, 12:25 PM |
iago | 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: [code]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 } }[/code] Is that the best way to do it? | August 6, 2003, 12:52 PM |
Adron | If I was a compiler, I might do something like this: [code] 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 } } [/code] The code is completely untested, but you get the idea? | August 6, 2003, 2:10 PM |
iago | 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 | August 6, 2003, 2:56 PM |
Yoni | That's pretty common, try for example: [code]int x = somebool ? 17 : 42;[/code] 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. | August 10, 2003, 11:19 PM |
Adron | Actually, later that same day I demonstrated that fact with this code: [code] typedef void somefuncptr(void); #define address1 0x12345678 #define address2 0x9abcdef0 ((somefuncptr*)(yourfunctionyoucall() ? address1 : address2)) (); [/code] which becomes [code] 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 [/code] 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" :) | August 11, 2003, 8:39 AM |
Grok | <ot> If you squint, it looks like Adron's code is trying to spell something ... "IRb --" </ot> | August 11, 2003, 11:40 PM |