关于《orange‘s一个操作系统的实现》中调用门部分的补充和纠正

在《orange‘s一个操作系统的实现》中书对调用门中参数复制一点一略而过,并没有对参数大小等做出解释!上网找了很久发现并没有太多这方面的描述于是自已动手实验了一下并查了80386指令手册得出如下结论:

经过实验发现:如果调用门是向32位代码段跳转时,那么调用门在用param count复制时以一个参数为双字大小进得复制,也是就要复制的参数大小为(param count)*4字节,如果调用门是向16位代码段跳转时,那么调用门在用param count复制时以一个参数为单字大小进得复制,也是就要复制的参数大小为(param count)*2字节。那么什么时候向32位代码段中跳转,什么时候向16位代码段中跳呢?这关系到门描述符中TYPE字段中的内容,如果TYPE字段的值为4则为16位门描述符用来向16位代码跳转,如果TYPE字段的值为c时则为32位门描述符,用来向32位代码段跳转!

在指令返回时本书中那副堆栈示意图旁边那段代码疑似有错误,因为RET 中的参数应与调用门中的(param count)就该是对应关系,也就是说如果是16位调用门跳转时返回时应用retf/ret  (param count)*2来返回,如果是32位调用门跳转时返回时就用retf/ret  (param count)*4,这样堆栈才能平衡!但那一小段代码竟用ret 3!

以下为参考资料和实验代码:


Changing Size of Call
When adding 32-bit gates to 16-bit procedures, it is important to consider
the number of parameters. The count field of the gate descriptor specifies
the size of the parameter string to copy from the current stack to the stack
of the more privileged procedure. The count field of a 16-bit gate specifies
the number of words to be copied, whereas the count field of a 32-bit gate
specifies the number of doublewords to be copied; therefore, the 16-bit
procedure must use an even number of words as parameters.

There are three ways to cause a 16-bit procedure to execute a 32-bit call:
1. Use a 16-bit call to a 32-bit interface procedure that then uses a
  32-bit call to invoke the intended target.
2. Bind the 16-bit call to a 32-bit call gate.
3. Modify the 16-bit procedure, inserting an operand-size prefix before
  the call, thereby changing it to a 32-bit call.
Likewise, there are three ways to cause a 32-bit procedure to execute a
16-bit call:
1.
Use a 32-bit call to a 32-bit interface procedure that then uses a
16-bit call to invoke the intended target.

 

2. Bind the 32-bit call to a 16-bit call gate.
3. Modify the 32-bit procedure, inserting an operand-size prefix before
  the call, thereby changing it to a 16-bit call. (Be certain that the
 return offset does not exceed 64K.)
Programmers can utilize any of the preceding methods to make a CALL in a
USE16 segment match the corresponding RET in a USE32 segment, or to make a
CALL in a USE32 segment match the corresponding RET in a USE16 segment.


以下为代码:

代码: 


 

发表评论

nine + 1 =