我是关于大会的新手。几天前我读到了IA32架构中的内存分段/分页,现在我正在研究远程调用。
好的,通过IA32分段,有一个16位段寄存器和一个32位段偏移。它们一起形成逻辑地址/远指针(具有分页的分段)或线性地址(没有分页的分段)。 关于远程调用,我现在读到在跳转之前段寄存器(CS)和16位偏移是PUSHed。
问题:为什么这个偏移量为16位?它是段的内部选择器,而不是计算线性/逻辑地址的偏移量吗?
操作模式是否与远程调用有关?
感谢您的建议。
答案 0 :(得分:2)
您应该从编程到ELF或Windows 32位平面用户空间模型开始,其中包括:
malloc
,以获得比您开始时更多的内容。)内存在中分配pages ,每个4096字节(极少数例外),可以是可读,可写和可执行的任意组合; 32位指针可以指向任何页面上的任何字节。%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寄存器的当前值是 两者都推到了堆栈上。