views:

576

answers:

1

I'm trying to use assembly in C code using C variables. My code looks like this:

__asm { INT interruptValue };

Where 'interruptValue' is a variable I get from the user (e.g 15 or 15h). When I try to compile I get:

Assembler error: 'Invalid instruction operands'

I don't know what is the correct type for interruptValue . I tried long\int\short\char\char* but none of them worked.

+8  A: 

The INT opcode does not allow to specify a variable (register or memory) as an argument. You have to use a constant expression like INT 13h

If your really want to call variable interrupts (and I cannot imagine any case for doing so), use something like a switch statement to decide which interrupt to use.

Something like this:

switch (interruptValue)
{
   case 3:
       __asm { INT 3 };
       break;
   case 4:
       __asm { INT 4 };
       break;
...
}

EDIT:

This is a simple dynamic aproach:

void call_interrupt_vector(unsigned char interruptValue)
{    
    //the dynamic code to call a specific interrupt vector
    unsigned char* assembly = (unsigned char*)malloc(5 * sizeof(unsigned char));
    assembly[0] = 0xCC;    //INT 3
    assembly[1] = 0x90;    //NOP
    assembly[2] = 0xC2;    //RET
    assembly[3] = 0x00;
    assembly[4] = 0x00;

    //if it is not the INT 3 (debug break)
    //change the opcode accordingly
    if (interruptValue != 3)
    {
         assembly[0] = 0xCD;              //default INT opcode
         assembly[1] = interruptValue;    //second byte is actual interrupt vector
    }

    //call the "dynamic" code
    __asm 
    {
         call [assembly]
    }

    free(assembly); 
}
Frank Bollack
As a fun exercise, you could probably code a variable interrupt using self modifying code, you'd just have to change the value of the 2nd byte of the INT instruction to whatever interrupt you want.
Falaina
@Falaina: you need to take care for INT 3 as this has a different opcode, but otherwise sounds like a good idea.
Frank Bollack
@Falina: How exactly can I modify the code? All I can think of is putting the instruction in a different function and then changing some bytes with an offset from the function's address.
Eldad