I have an odd question. Let's say I wanted to call a 16-bit procedure from a 32-bit one using an address type override. Once I am in that 16-bit procedure, how do I access portions of that segment above a 16-bit offset of 0FFFFh?
Okay, let's clear something up first. In order to call 16 bit code from a 32 bit segment (or vice versa), you must use a gall cate. Simply using an override won't cut it. So, assuming you're using a call gate to access a 16 bit routine, you must remember that a 16 bit segment must in fact be assembled -AS- a 16 bit segment (meaning you have to specifically define a 16 bit segment, as opposed to the general flat memory model). Okay, assuming you're doing all of that, you should still be able to access memory above 0FFFFh, although it's not recommended that you try this. You should be able to use 32 bit pointers in a 16 bit segment, but if I remember correctly, they won't access above 65535, no matter what the actual value is. So, you have to include a 32 bit base address (ie: mov ax,). Since 16 bit segments don't limit you to only 16 bit registers, this command should assemble correctly in either 16 or 32 bit code. Whether it will execute, however, is a different matter. This is an extremely difficult thing to do in any operating system, and so I wouldn't recommend such a technique for a beginner in Windows programming. =)
Heh, sorry. I meant to say a call gate, not gall cate. =)
Oh, I thought you could just use an address size override...how do you do this with call gate and what is a call gate?
You should probably read a good book on protected mode programming, or Windows system programming to understand the basics behind mixing 16 and 32 bit code. Explaining it on this board in any amount of detail would take me a long time, and probably raise a bunch of concerns by the Windows programmers here. (Call gates are sometimes used in VxDs, but can also be used by virus programmers, and other drains on society. :)) But, here's a basic explanation without getting too deep into it. In an 286+ processor, there are two modes: real and protected. When designing protected mode, Intel must've reached a problem. How are you supposed to call a routine in a lower privilage level? (A privilage level is also called a 'ring' in Windows terminology). They answered this with the 'call gate'. Stored in descriptor format in either the LDT or GDT, this allows you to access a different privilage level, or even a different format (16 or 32 bit) from your current segment. As I'm sure you can already see, it's quite a complex task even without Windows! :) A good place to get information, and even ask questions about this, is www.sandpile.org, but be warned: sandpile is a totally CPU oriented place. They don't discuss any operating systems, or even PC computers...only the processor itself.
Don't forget the mode "virtual 86"... when windows opens a dos prompt, the dos prompt is in what's called "virtual 86", the dos program actually thinks the processor is a 8086. The reason for this 3rd mode, is because you can't go from protected to real, without rebooting. Just thought i would add that nice tidbit of info :)
"Don't forget the mode "virtual 86"... when windows opens a dos prompt, the dos prompt is in what's called "virtual 86", the dos program actually thinks the processor is a 8086. The reason for this 3rd mode, is because you can't go from protected to real, without rebooting." Wrong! This is only for the 286 processor (which conviently didn't have a V86 mode). The 386 and above, which is required for Windows 32 programming, allows you to set and reset the PE bit of CR0 (bit 0) to enter and leave protected mode at will. However, in a 286 processor, it is necessary to triple-fault the CPU to go from protected to real mode. :)
I wasn't trying to argue anything, just throwing a fact about the x86 processors used today, and i'm fully aware that the 286 doesn't include virtual x86 mode.
I have no problems with people posting facts about the basic CPUs, however I do have a problem when those facts are provided incorrectly. The 'fact' about processors being unable to return to real mode without rebooting is false. First, the term is 'triple-fault'. Reboot implies the entire computer must be reset, whereas triple-faulting forces the CPU to clear all it's registers and begin executing in real mode at F000:FFF0 (which you change in order to make it execute where you want it to). Secondly, this is only for 286 processors, which, although a good trivia tidbit, is rather useless to post on a Win32 forum. :) Another inconsistancy is with the V86 mode. Yes, V86 mode was designed for real mode, but it does not make the CPU think it's an 8086, just that it's in a virutal real mode. It was called Virtual 8086 only because programmers would recognize the 8086 with real mode. If you don't believe me, open up a DOS prompt, Debug, and type these bytes in at 100h (e 100): 0F 20 00 0C 01 0F 22 00 34 01 0F 22 00 CC then use go. The program does nothing of interest, but uses CR0 to enter and leave protected mode. V86 does not emulate an 8086...merely real mode. These are the facts for any who is truly interested. This is not an attack on anyone, least of all you, Jon. I've often asked for information on the CPU only to be given faulty, inaccurate, or confused information, so I know how frustrating it can be. I'm only trying to make sure that, anyone who wants this information has the most accurate information they can.
How many modes are available on the 8086? Just one, "Real Mode", thus virtual 86 mode does trick the program into thinking it's an 8086 or "Real Mode". So my fact is correct, also, in my book "Master Class Assembly Language", it says that the processor can't go from protected to real, unless the processor is reset, thus rebooted. Write some code to go from protected->real... i would like to see you prove that book wrong.
Well, now let's not forget the indisputable 80186. Running most of the PS/2s in the world, and I think PCjr, but don't quote me, it also only had real mode. Oh, and by the way, here's the program that PROVES how easy it is to leave protected mode in a 386: mov eax,cr0 or al,1 mov cr0,eax xor al,1 mov cr0,eax As Emeril Lagassee would say, BAM! However, this may not suit your requirements to m, so here's a MUCH better example. It's an entire program which runs specifically from a boot sector. 0000: MOV AX,7D0 0003: MOV DS,AX 0005: LGDT QWORD PTR  000A: MOV EAX,CR0 000D: OR AL,1 000F: MOV CR0,EAX 0012: JMP FAR 0008:0017 ; in 16 bit protected mode 0017: XOR AL,1 0019: MOV CR0,EAX 001C: JMP FAR 07C0:0021 ; in 16 bit real mode 0021: JMP 0021 ... 0100: 10 00 00 7D 00 00 00 00 0108: FF FF 00 7C 00 9B 00 00 ... 01FE: 55 AA Granted the program does almost nothing of any great interest, however it should in fact meet your requirements for proof, does it not? If you're still not convinced I actually DO know what I'm talking about, email me and I'll send you the program, and even tell you how to install and execute it. But I can assure you, it's no longer necessary to triple-fault the CPU in order to go from protected to real mode! x86.org and sandpile.org would agree with me, so if you still don't believe me, go there and present your facts, although don't be surprised if they cut your facts down to reality, as I have. At this point, yes it's a bit of a flame. I tend to get that way when I'm challenged...so I apologize to anyone caught in the crossfire, and I apologize to this ENTIRE web board. It's not meant to cover the basics of protected mode programming, however a person must always answer a challenge, especially if they can. This message was edited by Racso, on 2/18/2001 10:49:13 PM
Going back to the original question...... Under general windows programming, i think you are a little confused...for instance
will call a proc at the address es:. If this is a 16bit segment. It will run as a 16bit segment, if its a 32bit segment, it will run as a 32bit segment. But to add to this, there is two opcode prefixes 66h and 67h which override the operand size and the address size for an instruction.
assume es: nothing mov es,'any segment number' call fword ptr es:
And to add to this, unless you are VxD programming, all this will mean little to you, because to my knowledge, its not 'normal' to get a 16bit segment in the address space of your app that will be running at ring3.
;in a 32bit segment BYTE 066h mov eax,eax ;is actualy decoded as mov ax,ax ;And in a 16bit segement BYTE 066h mov ax,ax ;is actualy decoded as mov eax,eax
Well, even so, that's risky. Assuming that CALL FWORD PTR ES: will actually assemble, and assuming that it won't just call the address at es:, then you still have to worry about the privilage levels in EFLAGS, the selector, and in the descriptor. For instance, if the EFLAGS privilage is 3 and the selector is 3, but the descriptor is 2 or higher, you'll get an exception 0D, or page fault. But assuming everything is fine and is executed as you would expect it to, then sure. That's a way to do it without a call gate...but it's reliability is dubious to say the least. :)
Well it seems i stand corrected, i apologize. Anyways... if i run a dos protected mode program, why does it require i reboot?:(
There are a few reasons why Windows doesn't like protected mode programs -other- than other Windows programs running. First, protected mode can only exist if the programs are protected. To Windows' way of thinking, a DOS protected mode program or DPMI (though not all protected mode programs in DOS -ARE- DPMI) or even VCPI, then it's not safe and thus, Windows wants as little to do with it as possible. :) The reason is that the control registers (CR0, CR3, etc...) and the data (?) registers (DR0, DR6, DR7, etc.) have to be secure. You don't want these registers to change without warning, and without Windows being able to control it...or else all hell would break loose! So, if Windows can't emulate these registers effectively, the program is considered unstable, and execution ceases quickly. Most DOS protected mode programs, though, use DPMI or VCPI, and seem to be very stable under Windows...at least under 95 and 98; under Windows NT and 2000, they're probably far less stable. However, even though they may be stable, Windows will still often inform you that the program was meant for MS-DOS and may not run properly in Windows. I usually ignore the message because the programs seem to run fine. But, if they don't, you can try to limit the amount of DPMI/VCPI memory the program has access to by right- clicking on the program, selecting properties, and memory. If the problem is in the control registers, though, this may not have much effect.