Assembly 为什么0xFFFFFC是无效的访问地址?

Assembly 为什么0xFFFFFC是无效的访问地址?,assembly,cpu-architecture,y86,Assembly,Cpu Architecture,Y86,嗨,我在读一本教科书,上面说程序不能访问更大的地址 小于0xc000000(与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 我很困惑。我有两个问题: 为什么不允许程序访问大于0xc000000的地址,像0xc000

嗨,我在读一本教科书,上面说程序不能访问更大的地址 小于
0xc000000
(与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
我很困惑。我有两个问题:

  • 为什么不允许程序访问大于
    0xc000000
    的地址,像
    0xc000008
    这样的地址不是有效地址吗

  • 如果真的不允许程序访问大于
    0xc000000
    的地址,
    0xfffffffc
    低于(小于)0xc000000,那么为什么它会失败呢

  • 为什么不允许程序访问大于0xc0000000的地址,像0xc0000008这样的地址不是有效地址吗
  • 现代操作系统利用硬件的特性来防止运行中的应用程序相互干扰。这种隔离的主要组件是特权分离和虚拟内存

    虚拟内存(与物理内存相反)意味着代码访问的地址(例如
    mov
    指令)不是RAM的实际地址。相反,内存管理单元(MMU)利用页表将虚拟地址(VA)转换为物理地址(PA),然后再将其发送到RAM

    特权分离是由CPU(和MMU)强制执行的,它允许单个操作系统内核完全控制硬件,同时安全地运行多个用户应用程序

    将这两个概念放在一起,通常内核运行在虚拟内存的一个区域(用户空间无法访问),用户空间进程运行在另一个部分

    在Linux内核的x86 32位arch端口中,经常使用1-3拆分,为内核提供1 GB的VA空间,为每个用户应用程序保留3 GB的VA空间。因此:

    • 0x00000000-0xBFFFFFFF:用户空间
    • 0xC0000000-0xFFFFFF:内核
  • 如果确实不允许程序访问大于0xc0000000的地址,那么0xFFFFFC低于(小于)0xc0000000,那么为什么它会失败呢
  • 数据的表示方式(如在硬件寄存器或内存中)与解释方式(如有符号/无符号整数、浮点数、文本字符串、图像等)之间存在很大差异

    请注意,如果将0xFFFFFF解释为32位二补(有符号)整数,则得到-1。如果将其解释为无符号整数,则得到(2^32-1)=4294967295

    地址总是未签名的;一般来说,在硬件方面没有负数


    0xFFFFFC大于0xC0000000。因此,这里它是一个内核地址,任何试图访问它的用户空间应用程序都会出现故障并发送一个SIGSEGV信号

  • 为什么不允许程序访问大于0xc0000000的地址,像0xc0000008这样的地址不是有效地址吗
  • 现代操作系统利用硬件的特性来防止运行中的应用程序相互干扰。这种隔离的主要组件是特权分离和虚拟内存

    虚拟内存(与物理内存相反)意味着代码访问的地址(例如
    mov
    指令)不是RAM的实际地址。相反,内存管理单元(MMU)利用页表将虚拟地址(VA)转换为物理地址(PA),然后再将其发送到RAM

    特权分离是由CPU(和MMU)强制执行的,它允许单个操作系统内核完全控制硬件,同时安全地运行多个用户应用程序

    将这两个概念放在一起,通常内核运行在虚拟内存的一个区域(用户空间无法访问),用户空间进程运行在另一个部分

    在Linux内核的x86 32位arch端口中,经常使用1-3拆分,为内核提供1 GB的VA空间,为每个用户应用程序保留3 GB的VA空间。因此:

    • 0x00000000-0xBFFFFFFF:用户空间
    • 0xC0000000-0xFFFFFF:内核
  • 如果确实不允许程序访问大于0xc0000000的地址,那么0xFFFFFC低于(小于)0xc0000000,那么为什么它会失败呢
  • 数据的表示方式(如在硬件寄存器或内存中)与解释方式(如有符号/无符号整数、浮点数、文本字符串、图像等)之间存在很大差异

    请注意,如果将0xFFFFFF解释为32位二补(有符号)整数,则得到-1。如果将其解释为无符号整数,则得到(2^32-1)=4294967295

    地址总是未签名的;一般来说,在硬件方面没有负数


    0xFFFFFC大于0xC0000000。因此,这里它是一个内核地址,任何试图访问它的用户空间应用程序都会出现故障,并发送一个SIGSEGV信号。

    CPU没有任何东西会使大于0xc0000000的地址无效。这是操作系统的决定。Linux的默认配置是将内核放在1gb以上(>=0xC0000000)的内存中。这1gb的krnel内存映射到所有用户模式程序的地址空间中,因此默认情况下禁止使用用户模式代码。0xFFFFFFFC大于0xC0000000。Linux不在y86上运行,AFAIK。你真的在问x86 Linux吗?CPU并没有让大于0xc0000000的地址无效。这是操作系统的决定。Linux的默认配置是将内核放在1gb以上(>=0xC0000000)的内存中。这1gb的krnel内存映射到所有用户模式程序的地址空间中,因此默认情况下禁止使用用户模式代码。0xFFFFFFFC大于0xC0000000。Linux不在y86上运行,AFAIK。是