0

I was reading: https://www.aldeid.com/wiki/X86-assembly/Instructions/sidt

But have one question, where should I save?

I don't know if the memory in which I am going to save is empty to be used or that it's in range. So how should I choose that memory region?

Why?

I am writing my own function to store idt resister (of size 80 bits) and then another function to load it.

void my_store_idt(struct desc_ptr *idtr) {
asm ("SIDT "
    );
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
  • So you're writing your own OS, so you can run this in kernel mode? See the GCC manual (https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html) and https://stackoverflow.com/tags/inline-assembly/info for how to use an `"=m"(*idtr)` memory output operand, assuming this is GCC / clang. – Peter Cordes May 18 '21 at 20:23
  • 5
    Don't vandalize your posts. If you want to delete it, use the delete button. If that is not available, then you are not allowed to remove that content – hyper-neutrino May 18 '21 at 21:34

2 Answers2

3

You have two options. Either let the caller give you a place to store the description:

struct idt {
    void *base;
    unsigned short length;
};

void my_store_idt(struct idt *idt)
{
    asm volatile ("sidt %0" : "=m"(*idt));
}

or allocate the structure yourself and return it by value:

struct idt my_store_idt(void)
{
    struct idt idt;

    asm volatile ("sidt %0" : "=m"(idt));

    return (idt);
}

Using volatile makes sure the compiler doesn't assume you'll read the same IDTR every time.


Loading the IDT is done in an analogous manner, but using an input operand instead of an output operand:

asm volatile ("lidt %0" :: "m"(idt));
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
fuz
  • 88,405
  • 25
  • 200
  • 352
  • Thanks, it seems I asked the wrong question (won't delete this considering your effort) please see: https://stackoverflow.com/questions/67593550/inline-assembly-in-c –  May 18 '21 at 20:32
  • Just noticed that with `-masm=intel`, we get `sidt XMMWORD PTR [rdi]`. (The sizeof the struct, since we didn't use `__attribute__((packed))`.) GAS rejects that. AT&T syntax assembles fine; the addressing mode doesn't include the size. https://godbolt.org/z/5xWbxvWeo So it's not necessarily something that needs to be fixed. – Peter Cordes May 18 '21 at 21:47
  • 2
    Also note, `sidt` should also use `asm volatile` since it's reading data from a source (IDTR) that could be different on different executions. So it's not a pure function of its inputs, i.e. doesn't produce the same value every time for the duration of the program. – Peter Cordes May 18 '21 at 21:48
1

I don't know if the memory in which I am going to save is empty to be used or that it's in range.

Reserving space for stuff is something you do in C, with a struct desc_ptr idtr variable (local or global, doesn't matter) whose address you pass to this function. Just like any other function where you pass it a pointer to space to store the output. The fact that you do the actual write to the space via inline asm makes no difference to how this function works as part of a larger C program. (Or kernel I guess, since lidt is a privileged instruction).

@fuz's answer shows correct GNU C inline asm syntax with "=m"(*idtr) to tell the compiler that a C variable in memory is the output operand, getting it to pick an addressing mode. (Look at the compiler-generated asm for the whole functions on https://godbolt.org/z/hf3KacETv) See also

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847