From: erfarmer201 AT comcast DOT net (Eric Farmer) Newsgroups: comp.os.msdos.djgpp Subject: Question re IRET wrapper and rdtsc Date: 18 Nov 2002 15:35:46 -0800 Organization: http://groups.google.com/ Lines: 68 Message-ID: NNTP-Posting-Host: 128.244.67.244 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: posting.google.com 1037662546 24891 127.0.0.1 (18 Nov 2002 23:35:46 GMT) X-Complaints-To: groups-abuse AT google DOT com NNTP-Posting-Date: 18 Nov 2002 23:35:46 GMT To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Hello all, I am experimenting with DJGPP, and I have a couple of questions about a (serial port) interrupt handler I am working on. (For a bit of context, I am working on a random number generator based on timing radioactive decay events, each of which will generate a serial port interrupt.) 1. I am using _go32_dpmi_allocate_iret_wrapper and family to install the handler (see code below). Does my handler need the commonly-used cli/pusha preamble (and accompanying popa/sti), or does the wrapper code do this for me? I have been unable to decipher the djgpp source, and there seems to be conflicting advice out there. 2. Is the rdtsc inline assembly correct? Note that Intel suggests also calling cpuid to "serialize," which fills eax, ebx, ecx, and edx. My main question here is whether I have correctly accounted for "clobbered" registers. Any comments are appreciated. Thanks, Eric Farmer #include #include #include int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY; int irq = 1; void isr() { // cli? // pusha? unsigned long long tsc; asm volatile ("cpuid\n\t" "rdtsc" : "=A" (tsc) : : "bx", "cx"); // sti? ... outportb(0x20, 0x20); // popa? } int main() { _go32_dpmi_seginfo old_isr, new_isr; _go32_dpmi_get_protected_mode_interrupt_vector(irq + 8, &old_isr); new_isr.pm_offset = (int)isr; new_isr.pm_selector = _go32_my_cs(); _go32_dpmi_allocate_iret_wrapper(&new_isr); _go32_dpmi_set_protected_mode_interrupt_vector(irq + 8, &new_isr); ... _go32_dpmi_set_protected_mode_interrupt_vector(irq + 8, &old_isr); _go32_dpmi_free_iret_wrapper(&new_isr); return 0; }