IA32汇总远程调用和段偏移大小

时间:2014-06-27 00:05:50

标签: assembly x86 ia-32

我是关于大会的新手。几天前我读到了IA32架构中的内存分段/分页,现在我正在研究远程调用。

好的,通过IA32分段,有一个16位段寄存器和一个32位段偏移。它们一起形成逻辑地址/远指针(具有分页的分段)或线性地址(没有分页的分段)。 关于远程调用,我现在读到在跳转之前段寄存器(CS)和16位偏移是PUSHed。

问题:为什么这个偏移量为16位?它是段的内部选择器,而不是计算线性/逻辑地址的偏移量吗?

操作模式是否与远程调用有关?

感谢您的建议。

2 个答案:

答案 0 :(得分:2)

您应该从编程到ELF或Windows 32位平面用户空间模型开始,其中包括:

  • 您的进程可用的所有RAM都映射到4GB(2 32 - 字节)线性地址空间。 (并非所有的地址空间都必须由您的程序使用,并且您必须使用操作系统/ C库接口,例如malloc,以获得比您开始时更多的内容。)内存在中分配pages ,每个4096字节(极少数例外),可以是可读,可写和可执行的任意组合; 32位指针可以指向任何页面上的任何字节。
  • 只有一种绝对呼叫指令,它可以到达任何地址。
  • 出于所有实际目的,段和段寄存器不存在。 1
  • 有八个整数寄存器(%eax%ebx%ecx%edx%esi%edi%ebp%esp)所有这些都是32位宽并且可以保存一个地址。 %esp保留用作堆栈指针,其他可用于任何你喜欢的东西;但是你应该阅读你的操作系统定义的C调用约定,这样你就知道哪些寄存器是call-clobbered,哪些是调用保存(对于Windows和非Windows,它们是不同的,所以我可以&#39 ;告诉你)。

如果您愿意,也可以从64位平面用户空间模型开始;重要的区别是现在有16个整数寄存器,它们都是64位宽,调用约定更复杂,你的RAM现在被​​映射成2 48 字节的线性地址空间。

只有在完全掌握了CPU在此模式下的功能之后,您才应该考虑学习保护模式内核编程(您必须了解段和段寄存器,但仅作为详细信息)虚拟内存如何工作)或16位编程(其中段实际上重要)。就个人而言,我不会为16位模式而烦恼;它唯一被用于使用的只是勉强足够的引导加载程序代码来获得16位模式的 out

1 C库和操作系统可以发挥巧妙的技巧,使用%fs和/或%gs作为具有非常特定功能的附加指针,但是它们不能用于任何你喜欢的东西。在平面用户空间模型中根本无法使用%cs%ds%es%ss(更准确地说,设置平面模型需要它们要设置为固定值,然后再也不要更改。)

答案 1 :(得分:1)

“关于远程调用,我现在读到在跳转之前段寄存器(CS)和16位偏移是PUSHed。”

这是不正确的:如果当前CS段描述符指定32位段,则16位段寄存器和32位偏移被压入堆栈。如果当前CS段描述符指定16位段,则偏移量为16位。

来自英特尔®64和IA-32架构软件开发人员手册

  

3.3.5 32位和16位地址和操作数大小

     

使用32位寻址时,逻辑地址(或远指针)   由16位段选择器和32位偏移量组成   ...当前正在执行的代码段的段描述符定义了默认地址和操作数大小。

     

7.3.15.2远程控制转移指令

     

JMP和CALL指令(参见第7.3.8节“控制转移”   指令“)都接受远指针作为源操作数   将程序控制转移到当前段以外的段   被CS注册指出。当远程呼叫时   CALL指令,EIP和CS寄存器的当前值是   两者都推到了堆栈上。