Page 1 of 1

[inline asm] x86 INT instruction

Posted: Thu Dec 24, 2015 12:09 pm
by Neroku
Hello everybody,

I am working in protected mode, I set up the IDT and I would like to comfortably generate software interrupts in C.
Calling a function that takes the interrupt number as a parameter would be an elegant solution for me 8) :

Code: Select all

// generate interrupt no. 33
intr(33);
If we do a little research on the x86 INT instruction, we realize the instruction takes an 8-bit immediate value (we exclude INT 3).
Based on that, I tried to implement my C function. Therefore I used in the code below the constraint N with the first and only operand:

Code: Select all

static inline void intr(const uint8_t intr_num)
{
    asm volatile ("int %0" : : "N" (intr_num) : "cc", "memory");
}
Unfortunately this code is not compiling and I get the following error ](*,) :
include/intr.h: In function 'intr':
include/intr.h:21:5: warning: asm operand 0 probably doesn't match constraints
asm volatile ("int %0\n\t" : : "N" (intr_num) : "cc", "memory");
^
include/intr.h:21:5: error: impossible constraint in 'asm'
Two possible alternatives came to my mind:
  • 1) a preprocessor macro, so that the given parameter is directly encoded as a string by the C preprocessor and then concatenated by the compiler:

    Code: Select all

    #define intr(n) asm volatile ("int $" #n : : : "cc", "memory")
  • 2) we know that the opcode of the INT instruction consists of two bytes (excluding again INT 3): the first byte is 0xcd and the second one is the interrupt number. Based on that fact, we could always modify this last byte just before executing the INT instruction:

    Code: Select all

    static inline
    void intr(const uint8_t intr_num)
    {
        asm volatile (
                    "\tmovb   %0, 1+intpos\n\t"
                    "intpos:\n\t"
                    "\tint $0\n\t"
                    : 
                    : "r" (intr_num)
                    : "cc", "memory"
                     );
    }
    Although this code works, since the code and data segments fully overlap in my configuration, I don't consider this way to be elegant enough. It is actually a hack and it may become a source of problems in the future :? .


Does anyone have an idea on how to solve the error I got or a smarter alternative than these two explained above [-o<?


Thanks in advance :D

Re: [inline asm] x86 INT instruction

Posted: Thu Dec 24, 2015 12:52 pm
by Combuster
The self-modifying code version is the typical solution if you need a parametrised INT opcode. You can also opt for a 768-byte jump table with all 256 possibilities.

In general though, INTn for arbitrary n is a design failure: INTn is the sumo-wrestler edition of a function call, and there can be only very few in a tournament, and to get there they must all be famous and important. You're denying them that privilege by refusing to call a function by name instead.