I'm trying to use the high performance counter in a 16-bit Turbo Pascal 7 program (don't ask...) running in a WinXP DOS box. I can execute the RDTSC instruction with inline $0F, $31 and the contents of AX and DX are set to what look like sensible values, but how can I access the upper halves of EAX, EDX and write the result to 2 longword global variables?
2 Answers
If I read my documentation correctly, then you can access the 32-bit registers from real mode by using a 0x66 prefix to the opcode. Thus, inlining "$66 $50" should have the following effect: it pushes EAX on the stack, as a 32-bit value. Then you just pop the lower and upper halves as two normal (16-bit) pop
opcodes (you will get lower half first). For EDX, use "$52" instead of "$50".
(I have not tried this.)

- 72,986
- 14
- 147
- 189
-
Actually, IIRC 16/32 is orthogonal to real/protected (286 has segmentation and no 16 bits mode), prefix 66h just selects the other one (16/32) for the following insn. – ninjalj Apr 07 '11 at 18:59
-
Thanks @Thomas. That works. We also figured that preceding a mov [GlobalLongwordVariable], ax with a $66 should work as well, and it does. – rossmcm Apr 07 '11 at 21:42
-
@ninjalj: yes. The 0x66 prefix allows access to 32-bit registers from 16-bit code. Real mode, and the VM86 mode (real mode emulation), are 16-bit code (a WinXP DOS box runs code in VM86 mode). But you can also have protected 16-bit mode (what Windows 3.0 called "standard mode"). – Thomas Pornin Apr 08 '11 at 12:30
For using 32bit registers in DOS, you need either a DOS extender or flat real mode. The first will make it possible to write programs for protected mode (you need to switch the code generation model somewhere) and the latter will be a kind of 32 bit real mode. I doubt it will work in a DOS box, maybe a DOS emulator will work.
AFAIK (15 years...) Borland Pascal had a own DOS extender, RTM.EXE or something.
Switching to flat real mode: http://www.assembly.happycodings.com/code54.html

- 29,760
- 6
- 71
- 103