为什么 0xfffffffc 是一个无效的访问地址?
why 0xfffffffc is an invalid address to access?
你好,我在看一本教科书,它说不允许程序访问更大的地址
比 0xc0000000
(32 位版本的 Linux 就是这种情况),所以下面的汇编代码是无效的:
1. irmovl ,%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
,为什么会失败呢?
- why programs are not allowed to access addresses greater than 0xc0000000, isn't that address like 0xc0000008 a valid address?
现代操作系统利用硬件的功能来防止 运行ning 应用程序相互干扰。这种隔离的主要组成部分是权限分离和虚拟内存。
虚拟内存(相对于物理内存)意味着代码访问的地址(例如mov
指令)不是RAM的实际地址。相反,内存管理单元(MMU)利用页表到转换虚拟地址(VA)在将它们发送到 RAM 之前发送到物理地址 (PA)。
权限分离由 CPU(和 MMU)强制执行,并且允许单个操作系统 kernel 完全控制硬件,而安全地 运行 多个 用户 应用程序。
将这两个概念放在一起,通常是内核 运行 位于一个虚拟内存区域(用户space 无法访问),而用户space 进程 运行在另一部分。
在Linux内核的x86 32位arch移植中,经常使用1-3分割,提供1GB的VAspace给内核,剩下3GB的每个用户应用程序的 VA space。因此:
- 0x00000000 - 0xBFFFFFFF:用户space
- 0xC0000000 - 0xFFFFFFFF:内核
- if programs are really not allowed to access addresses greater than 0xc0000000, 0xfffffffc is lower(less) than 0xc0000000, so why it will fail?
数据的表示方式(例如在硬件寄存器或内存中)和数据的解释方式(例如 signed/unsigned 整数、浮点数、文本字符串、图像等)
请注意,如果您将 0xFFFFFFFF 解释为 32 位补码(带符号)整数,您将得到 -1。如果将其解释为无符号整数,则会得到 (2^32 - 1) = 4294967295.
地址总是无符号的;一般来说,当涉及到硬件时,没有负数。
0xFFFFFFFC 大于 0xC0000000。因此,这是一个内核地址,任何试图访问它的用户space 应用程序都会出错并被传递一个 SIGSEGV 信号。
你好,我在看一本教科书,它说不允许程序访问更大的地址
比 0xc0000000
(32 位版本的 Linux 就是这种情况),所以下面的汇编代码是无效的:
1. irmovl ,%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
,为什么会失败呢?
- why programs are not allowed to access addresses greater than 0xc0000000, isn't that address like 0xc0000008 a valid address?
现代操作系统利用硬件的功能来防止 运行ning 应用程序相互干扰。这种隔离的主要组成部分是权限分离和虚拟内存。
虚拟内存(相对于物理内存)意味着代码访问的地址(例如mov
指令)不是RAM的实际地址。相反,内存管理单元(MMU)利用页表到转换虚拟地址(VA)在将它们发送到 RAM 之前发送到物理地址 (PA)。
权限分离由 CPU(和 MMU)强制执行,并且允许单个操作系统 kernel 完全控制硬件,而安全地 运行 多个 用户 应用程序。
将这两个概念放在一起,通常是内核 运行 位于一个虚拟内存区域(用户space 无法访问),而用户space 进程 运行在另一部分。
在Linux内核的x86 32位arch移植中,经常使用1-3分割,提供1GB的VAspace给内核,剩下3GB的每个用户应用程序的 VA space。因此:
- 0x00000000 - 0xBFFFFFFF:用户space
- 0xC0000000 - 0xFFFFFFFF:内核
- if programs are really not allowed to access addresses greater than 0xc0000000, 0xfffffffc is lower(less) than 0xc0000000, so why it will fail?
数据的表示方式(例如在硬件寄存器或内存中)和数据的解释方式(例如 signed/unsigned 整数、浮点数、文本字符串、图像等)
请注意,如果您将 0xFFFFFFFF 解释为 32 位补码(带符号)整数,您将得到 -1。如果将其解释为无符号整数,则会得到 (2^32 - 1) = 4294967295.
地址总是无符号的;一般来说,当涉及到硬件时,没有负数。
0xFFFFFFFC 大于 0xC0000000。因此,这是一个内核地址,任何试图访问它的用户space 应用程序都会出错并被传递一个 SIGSEGV 信号。