Здравствуйте, remark,
Есть такая штука —
http://invisiblethings.org/papers/redpill.html
Она впринципе не совсем справляется с заявленными целями, поскольку у каждого ядра своя IDT. Но для идентификации процессора по-моему подойти должна
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Без шелкодов:
#include <windows.h>
#include <conio.h>
#include <stdio.h>
unsigned get_idt_base()
{
#pragma pack(push, 1)
struct { WORD limit; DWORD base; } idt;
#pragma pack(pop)
__asm lea ecx, idt
__asm sidt [ecx]
return idt.base;
}
int main()
{
for ( unsigned cpu = 0; SetThreadAffinityMask(GetCurrentThread(), 1 << cpu); ++cpu )
{
printf("CPU#%u IDT base is %x\n", cpu, get_idt_base());
}
_getch();
}
ЗЫ начиная с MSVC 2005 SP1 есть интринсик __sidt
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
Сорри за задержку — не было времени разобраться и проверить.
Выглядит очень круто!
На последних AMD, согласно документации выполняется 7 тактов. На Intel документации не нашёл, но на тех, на которых проверил, тоже порядка 7 тактов. Конвеер не сериализует.
Хммм... Странно, что я нигде не нашёл про неё. Вопрос неоднократно поднимался в USENET...
На многопроцессорных/многоядерных WinXP IDT действительно разная на каждый процессор. А есть какие-нибудь гарантии на этот счёт? Чем это обусловлено?
Ну хотя наврядли это уже измениться на Win32, Win2k. А на Viste уже есть GetCurrentProcessorNumber().
Получилось следующее:
unsigned* idt_table;
unsigned idt_table_size;
__declspec(thread) unsigned thread_cache_idt;
__declspec(thread) unsigned thread_cache_proc;
unsigned get_current_processor()
{
#pragma pack(push, 1)
struct idt_t
{
unsigned short size;
unsigned base;
};
#pragma pack(pop)
idt_t idt;
__sidt(&idt);
if (idt.base != thread_cache_idt)
{
for (unsigned i = 0; i != idt_table_size; ++i)
{
if (idt_table[i] == idt.base)
{
thread_cache_idt = idt.base;
thread_cache_proc = i;
break;
}
}
}
return thread_cache_proc;
}
Здравствуйте, remark, Вы писали:
R>На многопроцессорных/многоядерных WinXP IDT действительно разная на каждый процессор. А есть какие-нибудь гарантии на этот счёт? Чем это обусловлено?
Соотв. функция в WDK позволяет регистрировать ISR для произвольного поцессора:
The IoConnectInterrupt routine registers a device driver's InterruptService routine (ISR), so that it will be called when a device interrupts on any of a specified set of processors.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth