delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/03/17/13:25:54

From: clc5q AT cobra DOT cs DOT Virginia DOT EDU (Clark L. Coleman)
Newsgroups: comp.os.msdos.djgpp
Subject: Inline Assembler/CWSDPR0 (Privileged instructions)
Date: 17 Mar 1999 17:43:09 GMT
Organization: University of Virginia Computer Science Department
Lines: 52
Message-ID: <7copjd$mp6$1@murdoch.acc.Virginia.EDU>
NNTP-Posting-Host: cobra.cs.virginia.edu
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

In previous postings, I was informed that I could execute privileged
X86 instructions, such as WRMSR (write model-specific register), if I
did a "stubedit" on my executable and made it use CWSDPR0.EXE instead
of CWSDPMI.EXE to provide DPMI.

I followed those instructions (turned off DPMI in my AUTOEXEC.BAT,
rebooted, compiled/linked, did the stubedit). However, as I step
through the code in the debugger (gdb), I see that as soon as I step
over the WRMSR instruction, I get a SIGSEGV exception and cannot
continue. I will show the code below.

General questions:

1) Do I need to compile without debug info? I get the exception
whether or not I run through gdb, and got it before I ever compiled
using "gcc -g", but have made a few changes since then.

2) Can you really execute instructions like WRMSR in your own code
just by using stubedit to force use of CWSDPR0.EXE, or is there more
to it than that?

I am running DR-DOS 7.03 in a multi-boot configuration on a Pentium-II
with 128 MB of RAM, 2GB of disk space in the DR-DOS C: FAT16
partition, with 1GB unused. Displaying the results of the CPUID
instruction confirms that my CPU supports RDMSR and WRMSR
instructions. Triple-checking the values I am putting in the registers
before the WRMSR against info in Intel manuals confirms that proper
values are being passed to the WRMSR. Any help is appreciated.

Code snippet:

   asm volatile ("movl %0, %%ecx; xorl %%eax, %%eax; cdq"
                  : /* no outputs */
                  : "r" (PERFCTR0)
                  : "%edx");
   asm volatile ("wrmsr");
   /* zero out the PERFCTR0 register */


PERFCTR0 is a constant that is #define-d to be 0x00C1, or 193 decimal,
which is the MSR number of the first performance counter in the P6
family (Pentium Pro/Pentium-II). I originally had the WRMSR after the
CDQ instruction, but separated them just so I could display all the
register contents before the WRMSR executes. Display confirmed that
EDX:EAX are set to 0, and ECX to 193. Thus, WRMSR should write a
64-bit value of 0 to MSR 193. Instead, it raises a fault, which is
what I would expect when you try to execute a privileged instruction
(WRMSR) in User Mode, leading me to think that the stubedit was not
sufficient to permit executing this inline assembly.

Clark Coleman

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019