作者:zwjy2018 | 来源:互联网 | 2022-12-02 15:35
嗨,我正在阅读一本教科书,它说程序不允许访问大于的地址0xc0000000
(如32位版本的Linux的情况),因此汇编代码无效:
1. irmovl $1,%eax
2. xorl %esp,%esp // Set stack pointer to 0 and CC to 100
3. pushl %eax // Attempt to write to 0xfffffffc, will fail
我糊涂了.我有两个问题:
为什么程序不允许访问大于的地址0xc0000000
,是不是像0xc0000008
有效地址那样的地址?
如果真的不允许程序访问大于0xc0000000
,0xfffffffc
低于(小于)的地址0xc0000000
,那么它为什么会失败?
Jonathon Rei..
5
为什么程序不允许访问大于0xc0000000的地址,是不是像0xc0000008这样的地址有效地址?
现代操作系统利用硬件的功能来防止运行的应用程序相互干扰.此隔离的主要组件是权限分离和虚拟内存.
虚拟存储器(与物理存储器相对)意味着代码访问的地址(例如mov
指令)不是RAM的实际地址.相反,内存管理单元(MMU)充分利用了页表来翻译将其发送给RAM之前的虚拟地址(VA)到物理地址(PA).
权限分离由CPU(和MMU)强制执行,允许单个操作系统内核完全控制硬件,同时安全地运行多个用户应用程序.
将这两个概念放在一起,通常内核在虚拟内存的一个区域中运行(用户空间不可访问),而用户空间进程在另一个区域中运行.
在Linux内核的x86 32位arch端口中,经常使用1-3分割,为内核提供1 GB的VA空间,为每个用户应用程序留下3 GB的VA空间.从而:
0x00000000 - 0xBFFFFFFF:用户空间
0xC0000000 - 0xFFFFFFFF:内核
如果真的不允许程序访问大于0xc0000000的地址,0xfffffffc低于(小于)0xc0000000,那么它为什么会失败?
数据的表示方式(例如在硬件寄存器或内存中)和解释方式之间存在很大差异(例如有符号/无符号整数,浮点数,文本字符串,图像等)
请注意,如果将 0xFFFFFFFF 解释为32位二进制补码(带符号)整数,则得到-1.如果将其解释为无符号整数,则得到(2 ^ 32 - 1)= 4294967295.
地址总是无符号的; 一般来说,当它涉及硬件时没有负数.
0xFFFFFFFC大于0xC0000000.因此,这里是一个内核地址,任何试图访问它的用户空间应用程序都会出错并传递一个SIGSEGV信号.
1> Jonathon Rei..:
为什么程序不允许访问大于0xc0000000的地址,是不是像0xc0000008这样的地址有效地址?
现代操作系统利用硬件的功能来防止运行的应用程序相互干扰.此隔离的主要组件是权限分离和虚拟内存.
虚拟存储器(与物理存储器相对)意味着代码访问的地址(例如mov
指令)不是RAM的实际地址.相反,内存管理单元(MMU)充分利用了页表来翻译将其发送给RAM之前的虚拟地址(VA)到物理地址(PA).
权限分离由CPU(和MMU)强制执行,允许单个操作系统内核完全控制硬件,同时安全地运行多个用户应用程序.
将这两个概念放在一起,通常内核在虚拟内存的一个区域中运行(用户空间不可访问),而用户空间进程在另一个区域中运行.
在Linux内核的x86 32位arch端口中,经常使用1-3分割,为内核提供1 GB的VA空间,为每个用户应用程序留下3 GB的VA空间.从而:
0x00000000 - 0xBFFFFFFF:用户空间
0xC0000000 - 0xFFFFFFFF:内核
如果真的不允许程序访问大于0xc0000000的地址,0xfffffffc低于(小于)0xc0000000,那么它为什么会失败?
数据的表示方式(例如在硬件寄存器或内存中)和解释方式之间存在很大差异(例如有符号/无符号整数,浮点数,文本字符串,图像等)
请注意,如果将 0xFFFFFFFF 解释为32位二进制补码(带符号)整数,则得到-1.如果将其解释为无符号整数,则得到(2 ^ 32 - 1)= 4294967295.
地址总是无符号的; 一般来说,当它涉及硬件时没有负数.
0xFFFFFFFC大于0xC0000000.因此,这里是一个内核地址,任何试图访问它的用户空间应用程序都会出错并传递一个SIGSEGV信号.