Board index » delphi » eax with 16-bit Borland C++ 3.1

eax with 16-bit Borland C++ 3.1

I am not sure of how well an inline assembly instruction is going to work in
a macro.

If you wrote the instruction inline you probably could use an instruction
size prefix to change to 32 bit registers for the one instruction.

  #include "DOS.H"
        :
   __emit__(0x66);
   __emit__(0x0F);
   __emit__(0x31);

Your example declares 'time', 'time_low' and 'time_high' as unsigned, the
same as an unsigned int.  There are two problems with that.

-time is already the name of a function.  You should use a different name.
-You show an instruction storing the contents of the EAX register into the
variable.  EAX is 32 bits but an unsigned int is 16 bits.  For that to work
the variable should be an unsigned long.

This is something like I would try:

  #include "DOS.H"
        :
  #pragma inline
        :
    unsigned long time_val;

    asm db 0x66     /* same as __emit__(0x66);  */
    asm mov [time_val],ax

Borland C++ 3.1 is ancient, 1992, and has no 32 bit abilities.  Expect a
very hard road trying to do anything like that article you speak of does.

.  Ed

 

Re:eax with 16-bit Borland C++ 3.1


Hi Mr. Mulroy,

Question: what does the asm db 0x66 do?  I probably could download an Intel
Opcode, just wondering if you know off hand?

Thanks, I found someone else trying to do the same thing RDTSC, except with
Microsoft VC++ 1.52.  I adopted the code for this:
// This compiles under Borland C++ version 3.1 with no eax register.
double PC_Mhz = 450000000;        // This is my Intel CPU clock speed
// array element to contain 64 bit time
unsigned long int r_time[2];              // [0]= lower 64 bits, [1] = upper
64 bits
double r_value;                              // rdtsc 64 bit value

double read_rdtsc(void)
{
    asm db 0x0F, 0x31;
    asm db 0x66;
    asm mov word ptr r_time, ax;
    asm db 0x66;
    asm mov word ptr r_time[+4],dx;
    r_value = ( (double) r_time[1] * pow(2,32)) + r_time[0];
    return r_value;

Quote
}

Thanks,
Robert

Re:eax with 16-bit Borland C++ 3.1


The code you originally showed has the same issues with VC++ 1.52 as with
BC++ 3.1.

Quote
> Question: what does the asm db 0x66 do?
> I probably could download an Intel
> Opcode, just wondering if you know off hand?

I already told you that the 0x66 is an instruction prefix, an escape for
size.

That changes the the size of the paramters in the next instruction.  The
next instruction is one using 16 bit items so it is changed  to act on 32
bit items.

.  Ed

Re:eax with 16-bit Borland C++ 3.1


Hi there,

The program is compiled in Borland C++ 3.1 (16-bit) and it's a DOS program.
I think it's compiled in
large mode, when I execute asm db 0x0F, 0x31, Windows 95 gives me "Illegal
Instruction" and crash
the program.  I can execute it with the Windows 2000 machine right here?

I don't get it!  What is it with Windows 95 that is different than Windows
2000 and is there a work around?

This is dos program, not windows.
Thanks,
Robert
"Ed Mulroy (TeamB)" <e...@mulroy.org> wrote in message
news:3b8c1186$1_2@dnews...

Quote
> The code you originally showed has the same issues with VC++ 1.52 as with
> BC++ 3.1.

> > Question: what does the asm db 0x66 do?
> > I probably could download an Intel
> > Opcode, just wondering if you know off hand?

> I already told you that the 0x66 is an instruction prefix, an escape for
> size.

> That changes the the size of the paramters in the next instruction.  The
> next instruction is one using 16 bit items so it is changed  to act on 32
> bit items.

> .  Ed

Re:eax with 16-bit Borland C++ 3.1


Quote
> ...I execute asm db 0x0F, 0x31, Windows
> 95 gives me "Illegal Instruction" and crash
> the program.  I can execute it with the Windows
> 2000 machine...

I can't try anything to confirm, diagnose or fix this.  I'm about 500 miles
from my Win95 machine right now.

Just guessing:

Win95 may be running the processor in another mode.  If you ran it in full
screen DOS mode, try in a DOS window.  Also try Start|Shutdown|Boot in MSDOS
mode

.  Ed

Re:eax with 16-bit Borland C++ 3.1


"Ed Mulroy \(TeamB\)" <e...@mulroy.org> wrote:

Quote
>> ...I execute asm db 0x0F, 0x31, Windows
>> 95 gives me "Illegal Instruction" and crash
>> the program.  I can execute it with the Windows
>> 2000 machine...

>I can't try anything to confirm, diagnose or fix this.  I'm about 500 miles
>from my Win95 machine right now.

>Just guessing:

>Win95 may be running the processor in another mode.  If you ran it in full
>screen DOS mode, try in a DOS window.  Also try Start|Shutdown|Boot in MSDOS
>mode

If it helps any, 0f 31 is RDTSC according to debug. My 386 book
doesn't list it, so I wouldn't be suprised if it crashed something.

Re:eax with 16-bit Borland C++ 3.1


0x0F 0x31 gives an RDTSC instruction (read time-stamp counter).
This instruction can optionally be disabled by setting the
appropriate flag in CR4. If the flag is set, the instruction
can only be executed at privilege level 0. At any other
privilege level a general protection fault is produced. If the
flag is not set no restriction exists.

Since all user applications run at privilege level 3, setting
the flag would cause the GP fault. It looks like 2000 does not
bother to set the flag, but 95 does - though I can't see why
Microsoft would want to restrict this instruction.

Anyway, the only way to change things is to modify the flag.
Unfortunately, you've guessed it, reading and writing to the
control registers can only be performed at privilege level 0.
So basically, there's nothing you can do.

Re:eax with 16-bit Borland C++ 3.1


Hi George,

Thanks, sorry I haven't gotten back to you.

Do I need some kind of Windows 95 device driver to do RDTSC (via assembly),
but how do I
pass the results to a MS-DOS program running under Windows 95?

The only way around it was for me to boot into DOS real mode, but Windows
isn't running in the
background.

I assumed your reading the Intel manual on RDTSC, is there any way to
re-enable
some flag in CR4?  Maybe I can run this before executing RDTSC?  I need to
have a
ring 0 program (device) driver to re-enable some flag in CR4.  Once that is
done,
I can run my MS-DOS program to execute the RDTSC instructions.

Robert

Quote
"georgem" <georg...@talk21.com> wrote in message news:3b9e05c2$1_2@dnews...

> 0x0F 0x31 gives an RDTSC instruction (read time-stamp counter).
> This instruction can optionally be disabled by setting the
> appropriate flag in CR4. If the flag is set, the instruction
> can only be executed at privilege level 0. At any other
> privilege level a general protection fault is produced. If the
> flag is not set no restriction exists.

> Since all user applications run at privilege level 3, setting
> the flag would cause the GP fault. It looks like 2000 does not
> bother to set the flag, but 95 does - though I can't see why
> Microsoft would want to restrict this instruction.

> Anyway, the only way to change things is to modify the flag.
> Unfortunately, you've guessed it, reading and writing to the
> control registers can only be performed at privilege level 0.
> So basically, there's nothing you can do.

Other Threads