s16_04.htm

来自「Programmer s Reference Manual is an impr」· HTM 代码 · 共 200 行

HTM
200
字号
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><HTML><HEAD><TITLE>80386 Programmer's Reference Manual -- Section 16.4</TITLE></HEAD><BODY><B>up:</B> <A HREF="c16.htm">Chapter 16 -- Mixing 16-Bit and 32 Bit Code</A><BR><B>prev:</B><A HREF="s16_03.htm">16.3  Sharing Data Segments Among Mixed Code Segments</A><BR><B>next:</B> <A HREF="c17.htm">Chapter 17 -- 80386 Instruction Set</A><BR><P><HR><P><H1>16.4  Transferring Control Among Mixed Code Segments</H1>When transferring control among procedures in USE16 and USE32 codesegments, programmers must be aware of three points:<UL><LI> Addressing limitations imposed by pointers with 16-bit offsets.<LI> Matching of operand-size attribute in effect for the <A HREF="CALL.htm">CALL</A>/<A HREF="RET.htm">RET</A> pair andtheInterrupt/<A HREF="IRET.htm">IRET</A> pair so as to manage the stack correctly.<LI> Translation of parameters, especially pointer parameters.</UL>Clearly, 16-bit effective addresses cannot be used to address data or codelocated beyond 64K in a 32-bit segment, nor can large 32-bit parameters besqueezed into a 16-bit word; however, except for these obvious limits, mostinterfacing problems between 16-bit and 32-bit modules can be solved. Somesolutions involve inserting interface procedures between the procedures inquestion.<H2>16.4.1  Size of Code-Segment Pointer</H2>For control-transfer instructions that use a pointer to identify the nextinstruction (i.e., those that do not use gates), the size of the offsetportion of the pointer is determined by the operand-size attribute. Theimplications of the use of two different sizes of code-segment pointer are:<UL><LI> <A HREF="JMP.htm">JMP</A>, <A HREF="CALL.htm">CALL</A>, or <A HREF="RET.htm">RET</A> from 32-bit segment to 16-bit segment is alwayspossible using a 32-bit operand size.<LI> <A HREF="JMP.htm">JMP</A>, <A HREF="CALL.htm">CALL</A>, or <A HREF="RET.htm">RET</A> from 16-bit segment using a 16-bit operand sizecannot address the target in a 32-bit segment if the address of thetarget is greater than 64K.</UL>An interface procedure can enable transfers from USE16 segments to 32-bitaddresses beyond 64K without requiring modifications any more extensive thanrelinking or rebinding the old programs. The requirements for such aninterface procedure are discussed later in this chapter.<H2>16.4.2  Stack Management for Control Transfers</H2>Because stack management is different for 16-bit <A HREF="CALL.htm">CALL</A>/<A HREF="RET.htm">RET</A> than for 32-bit<A HREF="CALL.htm">CALL</A>/<A HREF="RET.htm">RET</A>, the operand size of <A HREF="RET.htm">RET</A> must match that of <A HREF="CALL.htm">CALL</A>. (Refer to <A HREF="#fig16-1">Figure 16-1</A>  .) A 16-bit <A HREF="CALL.htm">CALL</A> pushes the 16-bit IP and(for calls between privilege levels) the 16-bit SP register. The corresponding <A HREF="RET.htm">RET</A> must also use a 16-bitoperand size to <A HREF="POP.htm">POP</A> these 16-bit values from the stack into the 16-bitregisters. A 32-bit <A HREF="CALL.htm">CALL</A> pushes the 32-bit EIP and (for interlevel calls)the 32-bit ESP register. The corresponding <A HREF="RET.htm">RET</A> must also use a 32-bitoperand size to <A HREF="POP.htm">POP</A> these 32-bit values from the stack into the 32-bitregisters. If the two halves of a <A HREF="CALL.htm">CALL</A>/<A HREF="RET.htm">RET</A> pair do not have matching operandsizes, the stack will not be managed correctly and the values of theinstruction pointer and stack pointer will not be restored to correctvalues.<P>When the <A HREF="CALL.htm">CALL</A> and its corresponding <A HREF="RET.htm">RET</A> are in segments that have D-bitswith the same values (i.e., both have 32-bit defaults or both have 16-bitdefaults), there is no problem. When the <A HREF="CALL.htm">CALL</A> and its corresponding <A HREF="RET.htm">RET</A> arein segments that have different D-bit values, however, programmers (orprogram development software) must ensure that the <A HREF="CALL.htm">CALL</A> and <A HREF="RET.htm">RET</A> match.<P>There are three ways to cause a 16-bit procedure to execute a 32-bit call:<OL><LI> Use a 16-bit call to a 32-bit interface procedure that then uses a32-bit call to invoke the intended target.<LI> Bind the 16-bit call to a 32-bit call gate.<LI> Modify the 16-bit procedure, inserting an operand-size prefix beforethe call, thereby changing it to a 32-bit call.</OL>Likewise, there are three ways to cause a 32-bit procedure to execute a16-bit call:<OL><LI> Use a 32-bit call to a 32-bit interface procedure that then uses a16-bit call to invoke the intended target.<LI> Bind the 32-bit call to a 16-bit call gate.<LI> Modify the 32-bit procedure, inserting an operand-size prefix beforethe call, thereby changing it to a 16-bit call. (Be certain that thereturn offset does not exceed 64K.)</OL>Programmers can utilize any of the preceding methods to make a <A HREF="CALL.htm">CALL</A> in aUSE16 segment match the corresponding <A HREF="RET.htm">RET</A> in a USE32 segment, or to make a<A HREF="CALL.htm">CALL</A> in a USE32 segment match the corresponding <A HREF="RET.htm">RET</A> in a USE16 segment.<P><A NAME="fig16-1"><IMG align=center SRC="fig16-1.gif" border=0><H3>16.4.2.1  Controlling the Operand-Size for a Call</H3>When the selector of the pointer referenced by a <A HREF="CALL.htm">CALL</A> instruction selects asegment descriptor, the operand-size attribute in effect for the <A HREF="CALL.htm">CALL</A>instruction is determined by the D-bit in the segment descriptor and by anyoperand-size instruction prefix.<P>When the selector of the pointer referenced by a <A HREF="CALL.htm">CALL</A> instruction selects agate descriptor, the type of call is determined by the type of call gate. Acall via an 80286 call gate (descriptor type 4)  always has a 16-bitoperand-size attribute; a call via an 80386 call gate (descriptor type 12)always has a 32-bit operand-size attribute. The offset of the targetprocedure is taken from the gate descriptor; therefore, even a 16-bitprocedure can call a procedure that is located more than 64 kilobytes fromthe base of a 32-bit segment, because a 32-bit call gate contains a 32-bittarget offset.<P>An unmodified 16-bit code segment that has run successfully on an 8086 orreal-mode 80286 will always have a D-bit of zero and will not useoperand-size override prefixes; therefore, it will always execute 16-bitversions of <A HREF="CALL.htm">CALL</A>. The only modification needed to make a16-bit procedureeffect a 32-bit call is to relink the call to an 80386 call gate.<H3>16.4.2.2  Changing Size of Call</H3>When adding 32-bit gates to 16-bit procedures, it is important to considerthe number of parameters. The count field of the gate descriptor specifiesthe size of the parameter string to copy from the current stack to the stackof the more privileged procedure. The count field of a 16-bit gate specifiesthe number of words to be copied, whereas the count field of a 32-bit gatespecifies the number of doublewords to be copied; therefore, the 16-bitprocedure must use an even number of words as parameters.<H2>16.4.3  Interrupt Control Transfers</H2>With a control transfer due to an interrupt or exception, a gate is alwaysinvolved. The operand-size attribute for the interrupt is determined by thetype of IDT gate.<P>A 386 interrupt or trap gate (descriptor type 14 or 15) to a 32-bitinterrupt procedure can be used to interrupt either 32-bit or 16-bitprocedures. However, it is not generally feasible to permit an interrupt orexception to invoke a 16-bit handler procedure when 32-bit code isexecuting, because a 16-bit interrupt procedure has a return offset of only16-bits on its stack. If the 32-bit procedure is executing at an addressgreater than 64K, the 16-bit interrupt procedure cannot return correctly.<H2>16.4.4  Parameter Translation</H2>When segment offsets or pointers (which contain segment offsets) are passedas parameters between 16-bit and 32-bit procedures, some translation isrequired. Clearly, if a 32-bit procedure passes a pointer to data locatedbeyond 64K to a 16-bit procedure, the 16-bit procedure cannot utilize it.Beyond this natural limitation, an interface procedure can perform anyformat conversion between 32-bit and 16-bit pointers that may be needed.<P>Parameters passed by value between 32-bit and 16-bit code may also requiretranslation between 32-bit and 16-bit formats. Such translation requirementsare application dependent. Systems designers should take care to limit therange of values passed so that such translations are possible.<H2>16.4.5  The Interface Procedure</H2>Interposing an interface procedure between 32-bit and 16-bit procedures canbe the solution to any of several interface requirements:<UL><LI> Allowing procedures in 16-bit segments to transfer control toinstructions located beyond 64K in 32-bit segments.<LI> Matching of operand size for <A HREF="CALL.htm">CALL</A>/<A HREF="RET.htm">RET</A>.<LI> Parameter translation.</UL>Interface procedures between USE32 and USE16 segments can be constructedwith these properties:<UL><LI> The procedures reside in a code segment whose D-bit is set, indicatinga default operand size of 32-bits.<LI> All entry points that may be called by 16-bit procedures have offsetsthat are actually less than 64K.<LI> All points to which called 16-bit procedures may return also liewithin 64K.</UL>The interface procedures do little more than call corresponding proceduresin other segments. There may be two kinds of procedures:<UL><LI> Those that are called by 16-bit procedures and call 32-bit procedures.These interface procedures are called by 16-bit <A HREF="CALL.htm">CALL</A>s and use theoperand-size prefix before <A HREF="RET.htm">RET</A> instructions to cause a 16-bit RET.<A HREF="CALL.htm">CALL</A>s to 32-bit segments are 32-bit calls (by default, because theD-bit is set), and the 32-bit code returns with 32-bit <A HREF="RET.htm">RET</A>instructions.<LI> Those that are called by 32-bit procedures and call 16-bit procedures.These interface procedures are called by 32-bit <A HREF="CALL.htm">CALL</A> instructions, andreturn with 32-bit <A HREF="RET.htm">RET</A> instructions (by default, because the D-bit isset).  <A HREF="CALL.htm">CALL</A>s to 16-bit procedures use the operand-size prefix;procedures in the 16-bit code return with 16-bit <A HREF="RET.htm">RET</A> instructions.</UL><P><HR><P><B>up:</B> <A HREF="c16.htm">Chapter 16 -- Mixing 16-Bit and 32 Bit Code</A><BR><B>prev:</B><A HREF="s16_03.htm">16.3  Sharing Data Segments Among Mixed Code Segments</A><BR><B>next:</B> <A HREF="s16_03.htm"><A HREF="c17.htm">Chapter 17 -- 80386 Instruction Set</A><BR> </BODY>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?