[SOLVED] Intel x86 reference manual vs. BrokenThron.com

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

[SOLVED] Intel x86 reference manual vs. BrokenThron.com

Post by HugeCode »

Hi all. I found something interesting on this BrokenThorn page:
Entering v8086 Mode

These are the same steps involved when setting up v8086 mode. v8086 mode requires a user mode task in order to enter v86 mode. Thus, by doing the above, you can enter v86 mode as well. However, there is one slight modification needed.

Recall the format of the EFLAGS register. Bit 17 (VM) is the v8086 Mode Control Flag. Because we push a value for EFLAGS on the stack when performing an IRET, in order to enter v86 mode, just set bit 17 of EFLAGS before pushing it on the stack. This will cause IRET to set the VM bit in the EFLAGS register on return.
And this is what I found in Intel reference manual (Section 7.3.13.2 EFLAGS Transfer Instructions):
The PUSHF (push flags), PUSHFD (push flags double), POPF (pop flags), and POPFD (pop flags double) instructions
copy the flags in the EFLAGS register to and from the stack. The PUSHF instruction pushes the lower word of the
EFLAGS register onto the stack (see Figure 7-11). The PUSHFD instruction pushes the entire EFLAGS register onto
the stack (with the RF and VM flags read as clear)
.
I don't understand. Which from these is correct?:
  1. The PUSHFD reads VM bit and POPFD reads it as zero
  2. The PUSHFD operation doesn't read VM bit
Last edited by HugeCode on Sat Jun 29, 2013 2:09 am, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Intel x86 reference manual vs. BrokenThron.com

Post by Combuster »

In example 1, PUSHFD is never used, let alone mentioned. A value meant for EFLAGS is to be put on the stack.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Intel x86 reference manual vs. BrokenThron.com

Post by HugeCode »

Sorry, I forgot this:
Screenshot_2.png
By the tutorial, the way is to push it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Intel x86 reference manual vs. BrokenThron.com

Post by Combuster »

And now the code that doesn't belong to a different part of the tutorial, please. *facepalm*
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
MDenham
Member
Member
Posts: 62
Joined: Sat Nov 10, 2012 1:16 pm

Re: Intel x86 reference manual vs. BrokenThron.com

Post by MDenham »

Combuster wrote:And now the code that doesn't belong to a different part of the tutorial, please. *facepalm*
That part of the tutorial is badly written, actually; there isn't any code to do the switch to V86 mode given (just the vague "since you're pushing EFLAGS, you can just set it there" bit).

To the OP: To do this, you'll have to replace PUSHFD in the example given with this (note: EAX gets trashed by this; if you want to preserve EAX, it'll take some juggling in place of the stack-fixing):

Code: Select all

push eax
pushfd
pop eax ; gets the flags into somewhere useful
or eax, 00020000h ; sets VM bit
add esp, 4 ; fix stack so we overwrite the old value of EAX
push eax
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Intel x86 reference manual vs. BrokenThron.com

Post by Owen »

Oh come on... could you really have come up with a more convoluted way of modifying EFLAGS on the stack?

How about...

Code: Select all

mov eax, 00020000h ; sets VM bit
pushfd
or [esp], eax
(Yes, this also trashes EAX)
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Intel x86 reference manual vs. BrokenThron.com

Post by neon »

Hello,

The article summarizes the steps to enable virtual 8086 mode; we assumed the provided information from the article would be sufficient and that sample code would not be necessary. We discourage the use of pushf due to the transition between kernel mode and user mode; the process eflags is separate from the current kernel state (although to be fair, a better implementation of the routine should be in assembly only; only to execute the current user mode process or current thread.)

In any case, the software must push some value for the user mode eflags on to the current stack with eflags.VM (bit 17) set. Both MDenham's and Owen's method will work fine. Alternatively decide on some nice default eflags state (with bit 17 in that value set of course) and push that binary value rather then the eflags register itself.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
MDenham
Member
Member
Posts: 62
Joined: Sat Nov 10, 2012 1:16 pm

Re: Intel x86 reference manual vs. BrokenThron.com

Post by MDenham »

Owen wrote:Oh come on... could you really have come up with a more convoluted way of modifying EFLAGS on the stack?
It was early, and the original intent was to write something that didn't trash EAX. I forgot to rewrite it afterwards to remove some of the extra code once I realized it wasn't going to avoid trashing EAX.

And now, for the correct way to do this without trashing any registers:

Code: Select all

pushfd
or [esp], 00020000h
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Intel x86 reference manual vs. BrokenThron.com

Post by HugeCode »

neon:
Thanks.

I would like to ask why is there code fixing stack in that tutorial code. Maybe for removing EBP pushed? But why?
Post Reply