OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Oct 22, 2019 9:39 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Using instruction call in P-Mode,the pushing address bytes
PostPosted: Sun May 08, 2011 5:35 am 
Offline
Member
Member

Joined: Fri Nov 19, 2010 6:54 pm
Posts: 70
1.When I call anothet 32-bit code segment from 16-bit code segment in P-Mode,
I find it push address for 8 bytes,I am strange that the next instruction offset
address has 2 bytes in 16-bit,and it add selector for 2 bytes,so it shouldn't
has 8 bytes,why?
Code:
codecseg    segment use32
            assume cs:codecseg
cstart     proc far
           .......
             retf
cstart     endp
codecseg    ends

cseg1       segment   use16   
            assume  cs:cseg1
           ....
            call codecseg_sel:offset cstart
           ....
cseg1    ends

2.When I call anothet 16-bit code segment from 32-bit code segment in P-Mode,
I find it push address for 4 bytes,I am strange that the next instruction offset
address has 4 bytes in 32-bit,and it add selector for 2 bytes,so it shouldn't
has 4 bytes,why?
Code:
codecseg    segment use16
            assume cs:codecseg
cstart     proc far
           .......
             retf
cstart     endp
codecseg    ends

cseg1       segment   use32   
            assume  cs:cseg1
           ....
            call codecseg_sel:offset cstart
           ....
cseg1    ends



Top
 Profile  
 
 Post subject: Re: Using instruction call in P-Mode,the pushing address byt
PostPosted: Tue May 10, 2011 2:50 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2010 4:53 pm
Posts: 1047
Location: Scotland
I don't know, but I've never needed to call 16 bit code from 32 bit code or 32 bit code from 16 bit code. I've just done a couple of experiments now though, and here's the code in decimal form:-

Starting in 32 bit mode: 139 196 (move esp to eax), 163 143 175 0 0 (post contents of eax to the address 143 175 0 0, named esp1 below), 154 103 173 0 0 24 0 (far call to address 103 173 0 0 using 24 for the code segment - this is a call to the 16 bit code which is located another six bytes on from here), 195 (this is a near ret instruction to return control to my OS once all the experimental code has run), 0 0 0 0 0 (a bit of space before the 16 bit code - this is unimportant, but the next bit is the start of the 16 bit code which has just been called): 139 196 (move sp to ax), 163 147 175 (store contents of ax at the address labelled below as esp2), 144 144 (two nops to cover up my original prefixed far ret before I wrote the next piece of code - we're about to call some 32 bit code), 102 154 123 175 0 0 8 0 (far call to a piece of 32 bit code which starts after the next five bytes) 102 203 (prefixed far ret to return to original piece of 32 bit code after control is handed back to this 16 bit code from the 32 bit code that follows), 0 0 0 (more unimportant spacing), 139 196 (move esp to eax) 163 151 175 0 0 (store contents of eax at the address below labelled as esp3), 203 (far ret), 0 0 0 0 0 0 0 0 0 0 0 0 (more unimportant spacing), and now the important addresses which show where the stack was before and after the two far calls:-

esp1: 232 123 0 0

esp2: 224 123 0 0

esp3: 216 123 0 0

So, it's 8 bytes on the stack each time. It's important to note that when I called the 16 bit code I used an unprefixed far call which will therefore use a four byte address, two bytes of segment and two null bytes which must be to keep the stack aligned for maximum speed. When I called the 32 bit code from 16 bit code I had to use a prefix to force the far call to use a four byte address - I tried doing it without the prefix and using a two byte address instead, but it crashed, even though the code is all sitting in the lowest 64KB of memory. Maybe I made a mistake of some kind, but it may be that you have to use a prefixed call when calling 32 bit code from 16 bit code. I'll try again once I've posted this. To far ret from the 32 bit code is easy enough as it will simply use an unprefixed far ret instruction, but it appears that the prefix has to be used to far ret from 16 bit code to 32 bit code - when I tried it without it it crashed.

Anyway, I don't know if that information is of any use to you, but it hopefully answers your first question. As for your second question, surely there have to be 8 bytes put on the stack again (rather than just four) because the far ret needs a four byte address plus a two byte segment (plus two null bytes to maintain proper stack alignment).

EDIT: I've just had another go at calling the 16 bit code from 32 bit code using a prefixed far call with a two byte address, removing the prefix from the far ret as well to get back again, and again it crashed, so it does look as if you have to use four byte addresses plus segment (and two extra null bytes on the stack) to go either way. I could be wrong though. As I have no interest in using 16 bit mode code other than real mode for communicating with the BIOS for which I only need far jumps, I'm not going to bother researching this further, but I'm sure you can find the definitive answers in a processor manual if you look.

_________________
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: MSN [Bot] and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group