精华内容
下载资源
问答
  • P152 如果我们比较一下前面用到的几定位内存地址的方法(可称为寻址方式),就可以发现:(1) [idata]用一个常量来表示地址,可用于直接定位一个内存单元;(2) [bx]用一个变量来表示内存地址,可用于间接定位一个内存...

    P139 我们可以在汇编程序中,用'……'的方式指明数据是以字符的形式给出的。编译器将把它们转化成相对应的ASCII码。
    P152 如果我们比较一下前面用到的几种定位内存地址的方法(可称为寻址方式),就可以发现:
    (1) [idata]用一个常量来表示地址,可用于直接定位一个内存单元;
    (2) [bx]用一个变量来表示内存地址,可用于间接定位一个内存单元;
    (3) [bx+idata]用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元;
    (4) [bx+si]用两个变量表示地址;
    (5) [bx+si+idata]用两个变量和一个常量表示地址。
            可以看到,从[idata]到[bx+si+idata],我们可以用更加灵活的方式来定位一个内存单元的地址。这使我们可以从更加结构化的角度来看待所要处理的数据。

    展开全文
  • 先看一下两种的字节码表示(只截取了循环体部分):第一种:one变量声明在循环体之外第二种:one变量声明在循环体内部第二种方法会在栈开辟10个空间存引用地址,在堆开辟10个空间存实际内容。这种说法是错误。a...

    先看一下两种的字节码表示(只截取了循环体的部分):

    第一种:one变量声明在循环体之外

    第二种:one变量声明在循环体内部第二种方法会在栈开辟10个空间存引用地址,在堆开辟10个空间存实际内容。

    这种说法是错误的。aload_n指令表示加载栈帧局部变量表偏移量为n的变量;astore_n反之,表示存储[1]。对比源码和字节码可以看出,在第二种方法中,one只在栈中开辟了一个空间,位于局部变量表下标为3的位置。同理,在第一种方法中,one也只开辟了一个空间,位于局部变量表下标为2的位置。至于堆空间,每次新建对象都会在堆中为对象开辟空间,因此两种方法都会在堆中开辟10个对象所需的空间。

    那么list存放的是什么?是栈引用地址么?

    list存放的是对象在堆中的引用,栈中的变量保存的也是对象在堆中的引用。这个引用可以理解为对象的内存地址,但是具体实现需要看jvm。

    list底层是怎么实现存,怎么实现取的?

    list保存了对象的引用,因此可以通过引用来访问对象。可以类比C语言的指针访问。

    如果存的是对象的引用地址,那这10个引用地址存在了哪里?

    这些引用地址栈上有,由变量one存储(方法结束退栈后,这些空间会被回收)。堆上也有,位于list对象的空间上。

    list又是怎么通过对象的引用地址去堆里面寻找的,还要通过栈空间去寻找么?

    这个看jvm怎么实现。假设引用存储的是对象的内存地址,那么假如我要访问这个对象的某个属性,其实就是找个这个对象所在的地址,然后计算这个属性的偏移,就可以得到这个属性的内存地址。不需要通过栈空间,栈帧会在方法返回后被回收。其实看个图就明白它们的关系了。

    展开全文
  • 地址空间分为两种,一种是物理地址空间,它的地址空间和内存条代表主存,硬盘代表外村是直接映射关系。第二种是逻辑地址空间,指是应用程序所能看到的地址空间,它是一维,由十六位数字表示。所有逻辑地址...

     

    操作系统需要完成抽象逻辑地址空间,保护独立地址空间,提供可以访问共享的内存空间,还需要根据程序运行场景虚拟出更多的地址空间这4步。

    在操作系统中管理内存的方法包括:程序重定位、分段、分页、虚拟内存、按需分页虚拟内存等。

     

    一、地址空间 和地址的生成

    地址空间分为两种,一种是物理地址空间,它的地址空间和内存条代表的主存,硬盘代表的外村是直接映射的关系。第二种是逻辑地址空间,指的是应用程序所能看到的地址空间,它是一维的,由十六位数字表示。所有逻辑地址空间都会落实在一个物理地址空间上,这个映射规则由操作系统完成。

    1)逻辑地址的生成

    以Linux下的GCC的编译过程为例gcc的编译过程分为三步:

    第一步将  文件1.c  文件2.c   文件3.c 分别通过编译器解析成汇编语言   文件1.s  文件2.s   文件3.s     。    可执行命令   gcc  -S  文件1.s  文件2.s   文件3.s    只激活预处理,和编译

    第二步将   文件1.s  文件2.s   文件3.s 分别通过汇编器  文件1.o  文件2.o   文件3.o      。     可执行命令   gcc  -c  文件1.s  文件2.s   文件3.s    只激活预处理,和编译和汇编,生成obj目标代码文件

    第三步将这些文件通过链接器生成 out 的可执行文件 如果不想编译出来成  a.out 名字            可执行命令   gcc -o  新文件名   待编译文件名 

    合成a.out 的文件过程中将文件头的数据大小,代码段,bss段,数据段 通过符号表中的引用信息来进行合并。

    生成出来的a.out 文件包含四部分内容:

    1) 文件头 : 包含了文件的加载信息和大小,其中

        1.1) tsize = 代码段大小

        1.2) dsize = 包含了初始化全局变量和初始化静态局部变量的数据段大小。

        1.3) bsize  =包含了未初始化的全局变量和未初始化的静态局部变量的bss段大小。

         1.4) total_size =加载  a.out文件的总大小

    2)代码段:包含了可执行代码

    3)数据段: 包含了初始化全局变量和初始化静态数据

    4)符号表: 可选,用于调式。

    生成可执行文件后,通过一个loader方法将可执行文件上的段大小,偏移量映射到逻辑地址来进行正确的数据的访问和执行操作。

    2)物理地址的生成

    当CPU取到逻辑地址时,通过自身的MMU(内存管理单元),查询对应的物理地址 ,如果没有则到主存中去寻址。

     

     

     

    展开全文
  • 汇编 | 六、更灵活定位内存地址 这一篇主要介绍一个很重要内容,主要是关于汇编中,使用数组结构访问数据。 and 与 or 指令 我们知道,一个字符或是字母都有它ASCII码值,以及对应二进制表示,下面我们...

    汇编 | 六、更灵活的定位内存地址

    这一篇主要介绍一个很重要的内容,主要是关于汇编中,使用数组的结构访问数据。

    and 与 or 指令

    我们知道,一个字符或是字母都有它的ASCII码值,以及对应的二进制表示,下面我们就介绍一下对二进制数据的位操作;
    10111111B是一个二进制的数据,汇编提供了一种方法来对它逐位进行操作,我们来看一下:

    and 指令,表示与,当计算的两个位置都是1的时候,才能得到1,如:

    mov al,01100011B
    and  al,00111011B
    

    计算后将得到al中的值为 00100011B

    or 指令表示或,当计算的两个位置的值只要有一个位置是1,就会得到1,如:

    mov al,01100011B
    or  al,00111011B
    

    计算后得到 01111011B

    使用数组处理数据 [bx+idata]

    这里我们通过一个案例来学习数组的使用。
    编写程序,将 ‘BaSic’、‘MinIX’ ,第一个字符串全部转化成大写,第二个全部转换成小写。
    学习过高级语言的都知道,需要经过判断,来确定某个字符是否需要改变,但是在还不知道如何使用汇编判断的情况下,通过对字母ASCII码值的探究,发现大写字母的ASCII码值总是比对应的小写字母小20H,也就刚好在二进制表示的第六位上,我们只需要通过and或or指令将其修改为1或0就可以实现大小写的转换了,修改为1转换为小写,0为大写。
    下面看代码:

    assume cs:code,ds:data,ss:stack
    data segment
    			db 'BaSic'
    			db 'MinIX'
    data ends
    
    code segment
    start:		mov ax,data
    			mov ds,ax
    			mov cx,5
    			mov bx,0
    s:			mov al,[bx]
    			add al,11011111B
    			mov [bx],al
    			inc bx
    			loop s
    			
    			mov bx,5
    			mov cx,5
    s0:			mov al,[bx]
    			or al,00100000B
    			mov [bx],al
    			inc bx
    			loop s0
    			
    			mov ax,4c00h
    			int 21h
    code ends
    end start
    

    上面的程序使用了两次循环,分别将两个字符串,转化之后再放入了原位。

    但是上面的程序分成两个循环,部分代码有一定的冗余,为了简化代码,我们可以进行以下改进:

    assume cs:code,ds:data,ss:stack
    data segment
    			db 'BaSic'
    			db 'MinIX'
    data ends
    
    code segment
    start:		mov ax,data
    			mov ds,ax
    			mov cx,5
    			mov bx,0
    
    s:			mov al,0[bx]
    			and al,11011111B
    			mov 0[bx],al
    			mov al,5[bx]
    			or al,00100000B
    			mov 5[bx],al
    			inc bx
    			loop s
    			
    			mov ax,4c00h
    			int 21h
    code ends
    end start
    

    上面的程序,我们使用了 0[bx]以及5[bx] ,这样的方式同时访问了两个字符,这就类似于数组的,基于一个自定义的地址,然后使用bx进行逐个字符的索引。

    更灵活的使用地址访问

    下面在介绍以下 si 和 di ,这两个寄存器,它们不可以被分为两个8进制的寄存器,但是功能与bx一样,可以用于访问内存。
    加上bx之后,可以有以下组合:
    [bx+si+idata]
    [bx+di+idata]
    idata表示1,2,3…这样的自然数。
    我们通过两个程序来熟悉相关操作:
    1、将以下定义的字符串的首字母改为大写

    assume cs:code,ds:data,ss:stack
    data segment
    			db '1. file         '
    			db '2. edit         '
    			db '3. search       '
    			db '4. view         '
    			db '5. options      '
    			db '6. help         '
    data ends
    code segment
    start:	......
    code ends
    end start
    

    为了方便修改,每一个字符串都是刚好16个字节。
    下面我们直接写代码来实现程序:

    		mov ax,data
    		mov ds,ax
    		mov cx,6
    		mov bx,0
    		
    s:		mov al,[bx+3]
    		and al,11011111B
    		mov [bx+3],al
    		add bx,16
    		loop s
    

    很简单,这样就成功实现了。

    2、将以下定义的所有字符串中的前4个字母转化为大写

    assume cs:code,ds:data,ss:stack
    data segment
    			db '1. display      '
    			db '2. brows        '
    			db '3. replace      '
    			db '4. modify       '
    data ends
    stack segment
    			dw 0,0,0,0,0,0,0,0
    stack ends
    code segment
    start:	......
    code ends
    end start
    

    要完成以上程序,需要考虑一个问题,我们要使用循环来处理这四个字符串,在每个字符串内部们又要使用循环,来处理每一个字符,那么这里肯定要使用二重循环,但是在这里面临的主要问题是 cx只保存一次循环所需要的值 ,也就是说,当它在内部循环时,改变了由于loop改变了cx的值,这样一来,在处理完第一个字符串的时候,就不会再处理后面的字符串了。
    如何解决这个问题,我们需要在使用一个寄存器另外保存cx的值,在外部循环将要结束的时候,再放回cx中。
    下面看代码实现:

    		mov ax,data
    		mov ds,ax
    		mov cx,4
    		mov bx,0
    		
    s:		mov ax,cx
    		mov cx,4
    		mov si,3
    
    s0:	mov al,[bx][si]
    		and al,11011111B
    		mov [bx][si],al
    		inc si
    		loop s0
    		
    		add bx,16
    		mov cx,ax
    		loop s
    
    		mov ax,4c00h
    		int 21h
    

    这样就可以完成需求了,但是仍然存在问题,当我们的寄存器都需要使用的情况下,使用ax来暂存就不可能了,我们一般使用栈来帮助我们暂存数据,下面是实现代码:

    		mov ax,stack
    		mov ss,ax
    		mov sp,16
    		
    		mov ax,data
    		mov ds,ax
    		mov cx,4
    		mov bx,0
    		
    s:		push cx
    		mov cx,4
    		mov si,3
    
    s0:	mov al,[bx][si]
    		and al,11011111B
    		mov [bx][si],al
    		inc si
    		loop s0
    		
    		add bx,16
    		pop cx
    		loop s
    
    		mov ax,4c00h
    		int 21h
    

    以上方式运用了栈暂存数据,完成要求。

    展开全文
  • 数据在内存存储

    2021-02-01 22:50:20
    三种表示方式均有符号位和数值位部分,符号位都是用零表示正,用1表示负,而数值位三种表示方法各不同。 原码: 直接将二进制按照正负数形式翻译成二进制就可以。 反码: 将原码符号位不变,其他位依次按位取反...
  • 它要完成以下三件事:将分配程序标识为已经初始化,找到系统中最后一个有效内存地址,然后建立起指向我们管理内存指针。这三个变量都是全局变量: 清单 1. 我们简单分配程序全局变量 int has_...
  • 方法传递过程

    2018-03-07 23:00:06
    1.基本类型和引用类型在内存中的保存Java中数据类型...指向内存空间的地址,代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示地址的位置。基本类型包括:byte,short,int,long,char,float,...
  • 一个函数有内存,一块表示函数本身,另外一块表示原型。 如图, 栈中存放类和对象引用/指针; B01中存放静态方法/类方法,可以通过类名调用; B02中存放非静态方法/实例方法,通过对象调用; B03为实例obj...
  • 操作系统(内存管理)

    热门讨论 2009-09-20 12:55:25
    它要完成以下三件事:将分配程序标识为已经初始化,找到系统中最后一个有效内存地址,然后建立起指向我们管理内存指针。这三个变量都是全局变量: 清单 1. 我们简单分配程序全局变量 int has_...
  • 字节序的表示方法两种: 1>小端字节序(Little Endian):在表示变量的内存起始地址存放低字节,高字节顺序存放 2>大端字节序(Big Endian):在表示变量的内存起始地址存放高字节,低字节顺序存放。 程序实例: ...
  • 如果以上两种方法并不能完全解决问题,你试着用一下“IE修复”软件,并可以查查是否有病毒之类。 〔微软NET.Framework升级到1.1版应该没问题了〕 2:运行 输入cmd 回车在命令提示符下输入 for %1 in (%windir%\...
  • 这时候,就会出现上述内存不能为“read”错误,并指出被引用的内存地址为“0x00000000“。内存分配失败故障原因很多,内存不够、系统函数版本不匹配等都可能有影响。因此,这种分配失败多见于操作系统使用很长...
  • 可以看到里边用的是==也就是比较的两个对象的内存地址。object1.equals(object2)为true,则表示equals1和equals2实际上是引用同一个对象。 public boolean equals(Object obj) { return (this == obj); } 所以八...
  • little endian和big endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度跨越多个字节的数据的存放形式. 假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内存顺序的机器上从...
  •  每一个实体都有内存地址值  实体中变量都有默认初始化值  实体不在被使用,会在不确定时间内被垃圾回收器回收 方法区,本地方法区,寄存器 数组操作常见问题  数组脚标越界异常...
  • 演示了用两种方法来绘图, 方法1. 直接绘图到屏幕上, 同时绘图到内存位图上,内存位图不会立即贴到屏幕上减少了内存拷贝时间,提高了效率, 将来窗口失效时OnPait贴图到屏幕上. 这种方法的...
  • 1:关联容器和顺序容器 ...其中vector表示一段连续的内存地址,基于数组实现,list表示非连续内存,基于链表实现。deque与vector类似,但是对于首元素提供删除和插入双向支持。关联容器主要...
  • 大小端 大端(存储)模式:是指数据低位保存在内存的...三种表示方法均有符号位和数值位部分,符号位都是用0表示“正”,用1表示“负”。正数原、反、补码都相同,负数三种表示方法各不相同。 原码(负数):直...
  • Runtime01对象本质

    2019-09-01 20:44:41
    查看NSObject对象在内存内容,有两种方法 方法一: 第1步 第2步 第3步 方法二,用lldb命令来实现 打印对象:p(等价于print)表示打印、po表示打印对象。 读取内存: memory read/数量+格式+字节数 内存...
  •  如果我们想访问第二个元素的地址我们可以写成如下的两种方式: &a[1]; a+1//注意这里的表示就是将a数组的起始地址向后进一位,移动到第二个元素的地址上也就是a[0]到a[1]的过程!  数组名称和指针的关系其实...
  • 本章将讨论两种特性: T C P拦截和网络地址转换(Network Address Tr a n s l a t i o n,N AT),它们可以大大加强对网络中 数据流量控制能力。先介绍 T C P拦截,并讨论其特性以及它是如何在网络中实现。还...
  • 数据在内存中是如何存在呢? 我们不妨用VS2019调试窗口来看一下下面代码。 int main() { int a = 20; int b = -10;...计算机中有符号数有三种表示方法,即原码、反码和补码。有符号数分为正数和
  • java中equal和==区别

    2020-06-07 00:18:18
    Java中==和baiequal区别为: 1、== 表示 判断2个变量或对象实例是否指向du同一个zhi内存...Java compareTo() 方法用于两种方式比较: (1) 字符串与对象进行比较。 (2) 按字典顺序比较两个字符串。 代码示例: public
  • 保护模式什么实模式和保护模式这是CPU的两种工作模式,解析指令的方式不同。在实模式下,16位寄存器需要通过段:偏移的方法才能达到1MB的寻址能力。 物理地址 = 段值 x 16 + 偏移 此时段值还可以看成地址的一部分,...
  • 而引用类型的变量保存引用值,"引用值"指向内存空间的地址,代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示地址的空间里。Java的内存空间主要包括5部分:栈区,堆区,静态变量或常量存放...
  • 静态链表和动态链表区别

    万次阅读 多人点赞 2017-10-10 15:09:35
    静态链表和动态链表是线性表链式存储结构的两种不同的表示方式。 1、静态链表是用类似于数组方法实现的,是顺序的存储结构,在物理地址上是连续的,而且需要预先分配地址空间大小。所以静态链表的初始长度一般是固定...
  • 储存

    2020-02-25 22:33:45
    4位和8位的内存地址表示方法,比如0x0001或者0x00000001,这两种表示方法都是表示编号为1的内存地址,都只是一个地址编号,指向(或者说)一个1字节内存空间。 计算机存储器内存是以字节为基本单位,也即一个...
  •  所谓的小端模式,是指数据的高位保存在内存的高地址中,而数据的低位保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。...
  • 静态链表和动态链表是线性表链式存储结构的两种不同的表示方式。 1、静态链表是用类似于数组方法实现的,是顺序的存储结构,在物理地址上是连续的,而且需要预先分配地址空间大小。所以静态链表的初始长度一般是...
  • 链表形式【F】

    2020-05-25 23:53:12
    数据元素之间关系在计算机中有两种表示方法: 顺序映象, 非顺序映象. 对应两种存储结构: 顺序存储结构, 链式存储结构 线性结构就是一种逻辑关系,方便我们对数据进行研究但是不考虑真实存储结构 数据是什么? ...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 342
精华内容 136
关键字:

内存地址的两种表示方法