首页
学习
活动
专区
圈层
工具
发布

【Linux】地址空间&&虚拟地址

这个地址绝对不是物理地址,理论上修改了数据为300之后不可能在输出有100,访问一个地址怎么可能又是100也是300。这个地址在系统层面上称之为虚拟地址。...在32位和64位下的地址空间大小是不一样的,为了方便这里使用32位来表述。32位从低到高一个有4GB的地址空间范围,实际上这个地址空间当中打印出来的地址,是该空间内对应的地址。...其实PCB和地址空间都是在物理内存里面的,只不过要访问初始化全局数据的时候,不在地址空间上保存,地址空间只会提供线性连续地址,让用户之后通过虚拟地址的地址空间,将虚拟地址转化到为了物理内存中。...,所以在地址空间的初始化数据中就有它的地址虚拟地址,页表的左侧也有它的虚拟地址,在页表右侧就有它对应的物理地址。...所以虚拟地址相同而物理地址不同。 3. 进程调度 Linux中的nice值并不是能任意调度的,而是从-20到19,这40个数字之间变换。

1.4K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【linux】地址空间

    在Linux地址下,这种地址叫做 虚拟地址 我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理 OS必须负责将 虚拟地址 转化成 物理地址 。...虚拟地址空间中的地址通过内存管理单元(MMU)映射到物理内存地址。 2. 地址空间的作用 隔离性:每个进程有自己的虚拟地址空间,其他进程不能直接访问。...程序内部使用的地址都是基于虚拟地址空间,页表负责将这些地址实时映射到实际的物理内存地址,为程序的正确执行提供支撑 03.Linux2.6内核进程调度队列 前面提到的nice值范围在[-20,19]...在 Linux 2.6 内核中,进程调度得到了很大的改进,以提高系统的效率、响应性和可扩展性。...Linux 2.6 使用了一种称为 Ø(1)调度器 的调度算法,这种算法通过使用多个调度队列来达到高效调度。

    1.9K10

    指针(*)、取地址(&)、解引用(*)与引用(&)

    指针(*)、取地址(&)、解引用(*)与引用(&) C++ 提供了两种指针运算符,一种是取地址运算符 &,一种是间接寻址运算符 *。...指针与取地址 例程: int main() { int num = 3; int* p = # // 将变量num的地址取出来,存到指针p中 printf("%d 的地址是...而&num中的&是取地址操作符,当&作用于一个对象上时,它返回了该对象的地址,比如例程中的&num即是为变量num的地址。...("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p, *p); *p = 100; printf("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p...)解引用得到改地址所存的值 cout << *p << endl; 1 &操作符 取地址,将某个变量在内存中所存放的地址拿到 cout << &num << endl;

    1.3K20

    驱动开发:取进程模块的函数地址

    在笔者上一篇文章《驱动开发:内核取应用层模块基地址》中简单为大家介绍了如何通过遍历PLIST_ENTRY32链表的方式获取到32位应用程序中特定模块的基地址,由于是入门系列所以并没有封装实现太过于通用的获取函数...,本章将继续延申这个话题,并依次实现通用版GetUserModuleBaseAddress()取远程进程中指定模块的基址和GetModuleExportAddress()取远程进程中特定模块中的函数地址...; ULONG TimeDateStamp;} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;GetUserModuleBaseAddress(): 实现取进程中模块基址...,该功能在《驱动开发:内核取应用层模块基地址》中详细介绍过原理,这段代码核心原理如下所示,此处最需要注意的是如果是32位进程则我们需要得到PPEB32 Peb32结构体,该结构体通常可以直接使用PsGetProcessWow64Process...TRUE : FALSE;// 验证地址是否可读if (!

    70640

    驱动开发:取进程模块的函数地址

    在笔者上一篇文章《驱动开发:内核取应用层模块基地址》中简单为大家介绍了如何通过遍历PLIST_ENTRY32链表的方式获取到32位应用程序中特定模块的基地址,由于是入门系列所以并没有封装实现太过于通用的获取函数...,本章将继续延申这个话题,并依次实现通用版GetUserModuleBaseAddress()取远程进程中指定模块的基址和GetModuleExportAddress()取远程进程中特定模块中的函数地址...ULONG TimeDateStamp; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; GetUserModuleBaseAddress(): 实现取进程中模块基址...,该功能在《驱动开发:内核取应用层模块基地址》中详细介绍过原理,这段代码核心原理如下所示,此处最需要注意的是如果是32位进程则我们需要得到PPEB32 Peb32结构体,该结构体通常可以直接使用PsGetProcessWow64Process...TRUE : FALSE; // 验证地址是否可读 if (!

    64840

    一级指针和二级指针,取地址和不取地址调用函数区别及其应用

    参数传递:通过一级指针可以将变量的地址传递给函数,并在函数中修改变量的值。通过二级指针可以将指针的地址传递给函数,并在函数中修改指针指向的数据。...3.函数参数调用时取地址和不取地址的区别 #include #include struct Node{ int data; struct Node...然而,这里的参数head并未取地址传递,即没有改变main函数中的链表list。 运行以上代码,输出为空,因为链表并没有被正确构建。...为了解决这个问题,我们需要将头节点的指针的地址传递给insertNode函数。...函数后,可以正确构建链表,并输出结果: 1 2 3 通过取地址传递参数,可以在函数内部修改实际的链表,使对链表的操作在函数外部可见。

    41110

    15.1 套接字通过域名取IP地址

    h_name是主机名,h_addr_list是一个指向具有主机IP地址的地址列表的指针。hostent 是一个结构体,用于存储主机的基本信息,包括主机名、主机别名、IP 地址类型和地址列表等。...(IPv4或IPv6)*/ int h_length; /* IP地址长度 */ char **h_addr_list; /* IP地址列表 */};其中,h_name...字段是主机的官方名称,h_aliases字段是一个指向主机别名列表的指针,h_addrtype 字段指示地址类型(通常是 AF_INET 或 AF_INET6),h_length 字段是地址长度(通常为...在 IPv4 中,h_addr_list 指向一个由网络字节顺序的 4 字节整数(即 IPv4 地址)组成的数组,而在 IPv6 中则是指向由 16 字节无符号整数组成的数组(即 IPv6 地址)。...ptr) { return "None"; } // 解析地址类型 printf("地址类型: %s \n", (ptr->h_addrtype == AF_INET) ?

    2.8K40

    驱动开发:内核取ntoskrnl模块基地址

    模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程运行后加载的模块,内核模块指的是内核中特定模块地址...,本篇文章将实现一个获取驱动ntoskrnl.exe的基地址以及长度,此功能是驱动开发中尤其是安全软件开发中必不可少的一个功能。...图片那么如何使用代码得到如上图中所展示的基地址以及大小呢,实现此功能我们需要调用ZwQuerySystemInformation这个API函数,这与上一篇文章《驱动开发:判断自身是否加载成功》所使用的NtQuerySystemInformation...回到代码上来,下方代码就是获取ntoskrnl.exe基地址以及长度的具体实现,核心代码就是调用ZwQuerySystemInformation得到SystemModuleInformation,里面的对比部分是在比较当前获取的地址是否超出了..._SYSTEM_INFORMATION_CLASS{SystemModuleInformation = 0xb,} SYSTEM_INFORMATION_CLASS;// 取出KernelBase基地址

    95520

    Linux编程--地址计算

    // 获取第一个出现`-`位置的字符串 char *first_bar_pos = strchr(maps_line, '-'); // 计算maps中的地址大小...itself*/ +1/* space before privbit*/; // 如果当前内存页不可读,也不可执行的话,也就意味着不是我们要找的ELF文件的内存地址...= 'x') { continue; } } 在计算addr_size的时候,使用的两个(char *)的减进行运算,为何能得到地址的大小?...而first_bar_pos与maps_line则这是上面两个字符串的地址,那么这两个地址相减,就是5da215f000字符串的大小,正好是10个字节。 所以就认为计算出来的地址长度为10。...privbits 相应的,在获取到addr_size的大小之后,通过first_bar_pos+addr_size+1+1,获取到的字符数组首地址指向的就是r-xp这一段文本了。

    1.6K00

    Linux:进程地址空间

    可以通过代码的方式在不同的区域创建变量然后来取地址获取再进行比较  2、栈区和堆区是相对而行的!!  ...——>结论:我们平时C/C++里面使用的地址全都不是物理地址,而是虚拟地址! 用户是看不到物理地址的,而OS必须要负责将我们所看到的虚拟地址转化成物理地址!...虚拟地址可以一样,但是通过页表映射不同的物理地址,就可以让父子进程解耦,一旦发生了任何异常,你释放你的我释放我的。 3、通过页表的虚拟地址映射物理地址,可以随便取地址,甚至是乱序。...这是有Linux的内存模块去管理的,进程并不需要关心。 结论4:其实变量名在定义的时候就已经被转化成一个个虚拟地址了,而我们之所以有a和&a,本质上是为了区分想获取的是变量的值还是地址。...结论5:以前我们所学习的C内存管理,其实本质上是进程地址空间,而内存管理是由Linux替我们完成的,我们上层语言并不需要关心具体的细节,只需要正常去通过对应的线性地址去使用就行了。

    97510

    【Linux】进程地址空间

    首先我们可以肯定的是,这个地址一定不是物理地址!同一块物理地址访问到的值一定是一样的!...下面我们来讨论一下 二、进程地址空间 1、页表 我们在之前讲到的程序地址空间的说法其实是错误的,正确来说应该叫进程地址空间,上面我们所说的地址叫做虚拟地址,也叫做线性地址,既然叫做虚拟地址,那当然就不是真实的物理地址了...,也就是虚拟地址是相同的,我们不是复制出了两个地址空间,这里需要注意 内核空间中有父子进程的task_struct,它们里面有指向各自页表的指针 其中上方是父进程的地址空间,下方是子进程的地址空间,子进程直接复制父进程的地址空间...,然后再将g_val改成100,然后页表的物理地址指向该地址,这个过程是写时拷贝,我们前面提到过 其中MMU起到的作用是负责将进程虚拟地址转换为物理地址,当 CPU 需要访问内存时,会将虚拟地址发送给...,这个地址是可以直接被操作系统使用的,这是可以使用地址找到的最小单位,类似于bit这样的存储单元是没有地址的概念的 所以所谓的进程地址空间,本质上是一个描述进程可视范围的大小,地址空间内一定要存在各种区域的划分

    90510

    linux进程地址空间

    3.1地址空间简介 我们的程序存储区分为代码区,字符常量区,全局数据区,堆区,栈区等等几个部分,地址是有低地址到高地址进行增长的,我们把这个叫做地址空间; 在栈区定义的变量,这个先定义先入栈,后定义的变量后入栈...,怎么可能一个变量一个地址,但是这个变量的数值却不一样,这个就是因为这个打印的结果不是真实的物理地址,而是我们的虚拟地址; 3.3页表概念的引入 页表是一张显示这个虚拟地址和真真实的物理地址的关系的映射表...,这个虚拟地址子进程就是拷贝的父进程的,所以这个打印的结果是一样的,但是这个实际上的物理地址不是一样的; 3.4谈谈细节 到底什么是进程地址空间:数据总线排列组合形成的地址的范围[0,2^32); 进程地址空间实际上就是我们的进程的一个可以使用的范围...,我们可以在这个区域上面进行区域的划分,存放各种数据; 进程地址空间在内核里面就是一个内核对象结构体,这个结构体里面有地址区域的起始位置的地址start和终止位置的地址end; 3.5进程地址空间管理...; 因此这个里面存在缺页中断,就是这个虚拟地址空间没有对应的物理地址空间,就是这个页表上面的虚拟地址数量大于这个物理地址数量,就是因为这个物理空间不会一次性全部开辟,而是进行的惰性加载;实际上,我们之前介绍的这个写实拷贝

    71810

    初识Linux · 地址空间

    前言: 本文介绍的是有关地址空间,咱们的介绍的大体思路是,先直接看现象,通过现象我们引入地址空间的概念,然后是简单的介绍地址空间,如何理解地址空间等,在往后的学习中,我们大概会介绍地址空间3 - 4次,...我们平常写下的对某个对象取地址,本质上都是在虚拟内存层面上进行操作,并不是在物理内存上,那么上面代码写的,&g_val本质上就是个虚拟地址! 那么虚拟地址(内存)如何和物理地址(内存)进行联系呢?...所以地址空间本质上就是结构体,进程通过地址空间的所有地址来找到物理内存中对应的数据。 那么问题又来了,里面不是都存的虚拟地址吗,怎么通过虚拟地址来找物理地址呢? 这时候,页表就该引入了。...page_table_lock, in other configurations by being atomic. */ struct mm_rss_stat rss_stat; struct linux_binfmt...这里对于虚拟地址也带一嘴,虚拟地址哪里来的呢?为什么地址空间一来就有地址呢?

    70510

    Linux进程地址空间

    Linux进程地址空间是学习Linux的过程中,我们遇见的第一个难点,也是重中之重的重点。虽然它很难,但是,等我们真正懂得了这样设计的原理,我们不禁会感叹:这真的是太妙了。...;环境变量的地址比命令行选项的地址大。...如此我们就可以具体列出一个数据所在的地址。 我们来看看内核中是怎样设计的: 确实跟我们说的描述方式一模一样。 二.进程地址空间 我们在C/C++中的取地址操作,取的是内存中的地址?...arg_start,结束arg_end,环境段的开始env_start,结束env_end unsigned long saved_auxv[AT_VECTOR_SIZE]; struct linux_binfmt...2.父子两个进程修改同一变量的原理 写时拷贝技术 我们在取地址操作中得到的地址都是虚拟地址,虚拟地址通过一张表格和内存之间建立映射关系,进而通过虚拟地址找到真正的内存中的地址,得到代码和数据。

    91310

    【Linux】进程地址空间

    显示相同地址,却是不同的值 下面在Linux上验证 创建test.c文件 st.c  ⮀...假设是物理地址,不可能同一个变量的地址,而读取到不同的值 我们在语言层面用的地址,不是物理地址,而是虚拟地址或者线性地址、 2 ....1字节 定义一个整数相当于在内存中开辟4个字节,连续4个字节对应的起始地址对应整形变量的起始地址 一个整数4个字节,而每个字节都有自己的地址,所以一个整数要有四个地址,而正常来说会取首地址作为整数的地址...地址空间是一段线性范围,从全0到全FFFF(16进制),因为数字是线性的,每一个数字表示一个地址,每个地址对应一个字节 地址空间是线性结构的 4.确定地址空间 32位下地址空间默认为0-42亿多 假设空间范围为...对第一个问题的解答 直接用的是虚拟地址,找到地址不是目的,而是该地址所对应的内容 页表:将虚拟地址转化成物理地址,左侧填充虚拟地址,右侧填充物理地址 当有一个虚拟地址,通过特定的地址空间想访问特定的区域时

    3.8K10
    领券