内存地址是什么

逻辑上,内存是一个有序字节组成的数组,每个字节有唯一的内存地址,那这个地址到底是啥。
cpu通过数据,地址,控制总线完成与内存的交互。地址总线一共有32根,每一根的值是1或0。内存最基本的单位是字节,8个二进制。
内存地址是对每一个字节的映射。换句话说,是32位二进制数相对一个8位二进制数的映射。(数组是什么,是一个整数对某一个数组元素的映射)
内存地址是地址总线上所有位构成的一个值。用这个值可以操纵内存中唯一的一个字节。

如何快速有效的对字节寻址呢?最早最通用的cpu(80x86)中应用了一种称为段的寻址技术(现在仍然使用),就是对所有的字节分段访问。

在采用分段技术之前,cpu是直接面向内存访问,cpu的针脚上的值就是地址的值。分段后,cpu面向的是段地址和段内偏移地址(针脚上的值不再是直接的内存地址了),之后由某一个部件根据cpu给出的段地址和段内偏移地址换算出真正的内存地址。

既然本来就可以访问到内存,由何必费那么大劲搞一个分段的寻址方式呢? 跑一下题,描述一下分段技术应用的上下文。分段的出现在操作系统中,没有分段就没有操作系统。在此之前,还没有一个现代意义上的操作系统(之前都是批处理作业,不对内存划分空间)。再然后就能有汇编语言,有编译器,有高级程序语言,有更好看的窗口桌面,能有更好玩的游戏...

    分段提供了最基础的对内存的保护能力。如果不分段,没有任何方式不让一条指令访问某一个内存区域(程序员写的指令能读写任意一个内存地址内容,想想这样的后果)。那分段机制如何保护内存呢。
    在80x86中,段地址又叫段选择符,共16位,存放在CS、DS、ES、SS、FS、GS寄存器中,其中起作用的有14位。段偏移地址有32位。在操作系统层面,保存着一张大表(段描述符表,也叫GDT表,存在内存,在操作系统初始化时创建),这个表的的索引就是段地址,或者段选择符(终于知道为什么会叫选择了)。程序中的某条指令给出一个逻辑地址(就是段地址和段内偏移地址),通过段地址查GDT表,就能知道这个段是干啥的,这个段多大,这个段从哪开始,从哪结束,更重要的是它的访问权限,操作系统会比对正在运行程序指令的状态权限,来决定这条指令能不能访问该地址。通过段地址查GDT表,知道段的首地址,再加上段内偏移量,就可以得出物理内存地址了。


图片来自杨炯老师的《linux内核完全剖析》第五版
pdf下载地址:http://oldlinux.org/download/CLK-5.0-WithCover.pdf

原文地址:https://www.cnblogs.com/gengqzh/p/10500189.html

时间: 2024-10-18 06:23:37

内存地址是什么的相关文章

在控制台输出口,根据内存地址,找到被过度释放的对象!

在控制台输出口,根据内存地址,找到被过度释放的对象!,布布扣,bubuko.com

MIR2修改内存地址实现免蜡烛

显血:7A0D3:75EB超负重:99A40:76EBoffset原改防石化:00466F80:759000466F81:2E90稳如泰山:0046959D:2044004695A9:1438如影随行:004634E2:0001战斗退出:004620E6:7490004620E7:0D9000462162:749000462163:0A90004914CA:7490004914CB:0E9000491576:749000491577:0E90相对不卡:--|00463A8D:9900|0049B

C语言:内存地址分析 & sizeof和strlen用法总结

还是在大学时代接触的C语言,当时学习数组.指针等概念时,怎一个"晕"字了得.最近在学习之余,疯狂地恶补了相关知识,故总结之,如有错误,请大家多多指点. 一. 内存地址分析 1) 先来看一个最基础的例子: int a[4]; 提问:&a[0],  a,  &a,  a+1,  &(a+1),  &a+1 分别表示什么? 咋一看,真的不知所措: 我们可以图解来分析它(假设下面的操作均在32为系统上面). 先来对上图进行简单的说明工作: 1. 紫色区域就是数组

关于内存地址和内存空间的理解。

1.内存地址用4位16进制和8位16进制表示的区别.例如经常可以看到某些书籍上写的内存地址0x0001,在另外一些书籍上写的内存地址又变成了0x00000001.都是表示的编号为1的内存地址,为什么一个是4位16进制表示,另外一个又是用8位16进制表示呢? 首先,必须要知道内存地址只是一个编号,代表一个内存空间.那么这个空间是多大呢?原来在计算机中存储器的容量是以字节为基本单位的.也就是说一个内存地址代表一个字节(8bit)的存储空间. 例如经常说32位的操作系统最多支持4GB的内存空间,也就是

LMA(装载内存地址)与VMA(虚拟内存地址)

      关于LMA和VMA,这个问题,有点点小复杂,不过,此处,我会把我的理解,尽量通过通俗的方式解释出来,以方便理解.当然,鄙人水平有限,难免有错,希望各位批评指正.       一般提及LMA和VMA,多数情况都是和ld,链接器相关的.在了解这两个名词的详细含义之前,有些基本知识和前提要说一下: [基础知识] 1.从你写的源代码到执行你的程序,一般经历了这几个过程:源代码编辑 -> 编译 -> 链接 -> 装载 -> 执行 2.编译,简单说就是用编译工具,将你的源码,变成可

C语言精要总结-内存地址对齐与struct大小判断篇

在笔试时,经常会遇到结构体大小的问题,实际就是在考内存地址对齐.在实际开发中,如果一个结构体会在内存中高频地分配创建,那么掌握内存地址对齐规则,通过简单地自定义对齐方式,或者调整结构体成员的顺序,可以有效地减少内存使用.另外,一些不用边界对齐.可以在任何地址(包括奇数地址)引用任何数据类型的的机器,不在本文讨论范围之内. 什么是地址对齐 计算机读取或者写入存储器地址时,一般以字(因系统而异,32位系统为4个字节)大小(N)的块来执行操作.数据对齐就是将数据存储区的首地址对齐字大小(N)的某个整数

11.用C对32位内存地址的访问方式

使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义 #define RAM_ADDR     (*(volatile unsigned long *)0x0000555F)     然后就可以用C语言对这个内存地址进行读写操作了     读:tmp = RAM_ADDR:     写:RAM_ADDR = 0x55: 定义volatile是因为它的值可能会改变,大家都知道为什么改变了: 如果在一个循环操作中需要不停地判断一个内存数据,例如要等待RAM_ADDR的I标志位置位,因

精通Hibernate——Java的内存地址与Hibernate的内置对象标识符

在Java语言中,判断两个对象引用变量是否相等,有以下两种比较方式: (1)比较两个变量所引用对象的内存地址是否相同,"=="就是比较的内存地址.此外,在Object类中定义的equals(Object o)也是按内存地址来比较的.如果用户自定义的类没有覆盖equals(Object o)方法,也是按照内存地址来比较的.例如,以下代码用new语句共创建了两个Customer对象,,并定义了三个Customer类型的引用变量,c1,c2,c3: Customer c1 = new Cus

更灵活的定位内存地址的方法(学习汇编)

1.and指令:逻辑与指令,按位进行与运算.与1不变,与0变0,可将对象相应位设为0. 2.or指令:逻辑或指令,按为进行或运算.或1变1,或0变0,可将对象位设为1. 3.[BX+idata]的几种表现形式: mov ax,[200+bx] mov ax,200[bx] mov ax,[bx].200 4.SI和DI是8086CPU中和Bx功能相似的寄存器,只是不能分成两个8位的寄存器来用. 5.[BX+SI]进行内存地址定位的几种形式: mov ax,[bx][si] mov ax,[bx+

用2种内存模型来排序字符串的的顺序,一种是交换内存地址,第二种是交换内存里面的值;

#define _CRT_SECURE_NO_WARNINGS #include"stdio.h" #include"stdlib.h" #include"string.h" void MyPrintf(char **); void MYSORT(char **, int); void SORTBUF(char **); void main() { int i = 0; int j = 0; char *buf; char **myarray;