I'm running into a snag using the _emit pseudoinstruction, but more accurately a snag using the C preprocessor. I have an array of op codes from which I want to randomly select one and _emit it into the program's code. Here is an example:

unsigned char opcodes[] = { 
  0x60, // pushad
  0x61, // popad
  0x90  // nop
}

int random_byte = rand() % sizeof(opcodes);
__asm _emit opcodes[random_byte]; // optimal goal, but invalid

However, it seems _emit can only take a constant value. E.g, this is valid:

switch(random_byte) {
  case 2:
    __asm _emit 0x90
    break;
}

This is also valid:

switch(random_byte) {
  case 2:
    #define OP 0x90
    break;
}

__asm _emit OP

But this becomes unwieldy if the opcodes array grows to any considerable length, and also essentially eliminates the worth of the array since it would have to be expressed in a less attractive manner.

Is there any way to neatly code this to facilitate the growth of the opcodes array? I've tried other approaches like:

#define OP_0 0x60
#define OP_1 0x61
#define OP_2 0x90

#define DO_EMIT(n) __asm _emit OP_##n

// ...

unsigned char abyte = opcodes[random_byte];
DO_EMIT(abyte)

In this case, the translation comes out as OP_abyte, so it would need a call like DO_EMIT(2), which forces me back to the switch statement and enumerating every element in the array.

It is also quite possible that I have an entirely invalid approach here. Helpful feedback is appreciated.

Considering the fact that you will need to recompile to accept new opcodes regardless is there any reason you can't generate this code with some scripting language and just use that? Something like:

int main () {
   /* ... */
   switch (random_value) {
#include "generated_switch_body.code"
   default: break;
   }
   return 0;
}

Where generated_switch_body.code is generated by the script. It would look something like

case 0: __asm _emit 0x60
break;
case 1: __asm _emit 0x61
break;
case 2: __asm _emit 0x90
break;

It's not the prettiest solution, but I don't see a way to do what you want directly with macros.

Edited 5 Years Ago by L7Sqr: n/a

I changed course and have been doing that. Essentially writing a wrapper that unwinds all combinations and enumerates individual #define declarations. Can't win them all, I suppose. Thanks for the reply.

This article has been dead for over six months. Start a new discussion instead.