Chinaunix

标题: effecitve address作何解释? [打印本页]

作者: valpa    时间: 2008-09-01 21:07
标题: effecitve address作何解释?
比如LEA语句,LEA r32, m意思是load effective address fro m in register r32.
这里的effecitve address何解
作者: freearth    时间: 2008-09-01 21:11
有效地址,就是你的软件访问内存是用的地址。
物理地址,CPU发送到地址信号线上的地址。
这两个可能是相同的,也可能是不同的。软件使用的时候,只要使用“有效地址”就行。
微机原理里面详细讲过。

原帖由 valpa 于 2008-9-1 21:07 发表
比如LEA语句,LEA r32, m意思是load effective address fro m in register r32.
这里的effecitve address何解

作者: mik    时间: 2008-09-01 22:26
标题: 回复 #2 freearth 的帖子
freearth 的回答挺不错 看来基础不错

不过,能再完整一些就好了。
作者: mik    时间: 2008-09-01 22:35
标题: 回复 #2 freearth 的帖子
解释“effecitive address“ 这个问题,既然提到了 physcial address,怎能不提 virtual address。

完整的解释 effective address,应该要结合三者来说。
effecitive address 是程序员,软件所能看到的地址形式,在CPU指令层里也就只能看到这种形式。
virtual address 不是程序员,软件能触及的地址形式,virtual address 是经过 CPU MMU 单元所产生的产物。
pysical address 同样不是软件能使用到的。也是 CPU MMU 单元的产物。
作者: freearth    时间: 2008-09-01 23:23
“virtual address 不是程序员,软件能触及的地址形式,virtual address 是经过 CPU MMU 单元所产生的产物”
这句话有些问题吧。
在支持虚地址的机器上(CPU支持且操作系统支持),effecitive address和virtual address是相同的。都是程序员以及软件使用的地址。编译器生成的可执行程序中的所有地址都是这样的地址,在CPU内部执行的所有指令使用的地址也都是这样的地址。当CPU将这种地址发向总线的时候,有效地址(虚拟地址)会经过MMU进行虚实地址的转换,变换成物理地址(physical address),发到地址总线上。地址总线上总是物理地址。
在不支持虚地址的机器上(CPU没有MMU或是操作系统不支持,例如DOS),effecitive address和physical address是相同的。程序中使用的地址,CPU中执行指令的地址,以及地址总线上的地址是相同的,这时没有虚拟地址这个概念,effective address也不会经过MMU的变换。

从上面可以看到,在不同的情况下,程序员使用的可能是虚拟地址,也可能是物理地址。而有效地址不管在哪种情况下都是表示程序员(软件)使用的地址,也就是CPU内部指令使用的地址。

由于X86的地址空间是分段的,所以,其实X86的有效地址的概念还有些诡异,在实模式下,这个“有效地址”是在当前段的中的偏移地址,还不是物理地址。

原帖由 mik 于 2008-9-1 22:35 发表
解释“effecitive address“ 这个问题,既然提到了 physcial address,怎能不提 virtual address。

完整的解释 effective address,应该要结合三者来说。
effecitive address 是程序员,软件所能看到的地 ...

作者: mik    时间: 2008-09-01 23:49
原帖由 freearth 于 2008-9-1 23:23 发表
“virtual address 不是程序员,软件能触及的地址形式,virtual address 是经过 CPU MMU 单元所产生的产物”
这句话有些问题吧。
在支持虚地址的机器上(CPU支持且操作系统支持),effecitive address和virtu ...


effecitive address 和 virtual address 是不同的,无论是从概念上讲,还是软件层来讲,或是指令层来讲。

effecitive address 是地址形式是:[base+index*scale+disp],是指令层面上地址元素。是最原始的。

virtual address 也就是 linear address(线性地址)代表CPU层面上寻址空间。是一个MMU产物。
  MMU 包括两部分:segmentation 及 paging,linear address 地址就是经过 segmentation 后的产物。

physical address 是经过 paging 后的产物。


举个例子,很简单

mov ax, [1234]
-----------------------
[1234] 就是有效地址形式,若ds:f000,dos 下经过 segmentation 后,就是 f1234,这个地址就是 linear address (vritual)
当然,此时的 linear address 就是 physical address。


这里,又引出另一个概念,逻辑地址。

逻辑地址形式是:selector :  effecitive address


mov ax, es:[1234]
---------------------
es:[1234] 这就是逻辑地址。 
这里,[1234]是有效地址,若是: lea ax, es:[1234] 得到的是 ax = 1234


在保护模式下,这种分别就更加明显,这里就不说多了
作者: freearth    时间: 2008-09-02 00:55
[base+index*scale+disp],是指令层面上地址元素。是最原始的
我记得这个是指令系统体系结构中的“寻址模式”而不能叫做有效地址。比如,
lea r,[base+index*scale+disp]
你是把“
[base+index*scale+disp]”计算出来的值放入了寄存器中,这个值是一个数字,二进制无符号数,这个数字是地址,这条指令并不是把“[base+index*scale+disp]“存入寄存器。

我们暂时不要用X86举例子,看一个物理地址空间不分段的处理器,例如power

虚拟地址是指在虚拟地址空间中的地址(虚拟地址空间是MMU和操作系统协作,为每一个进程创建的一个独立的地址空间)。MMU的作用就是将虚拟地址转换成物理地址。这个转换是通过页表来做的。当然,页表可能是二级的。

线性地址是一个不准确的概念,准确而言,地址空间分为线性地址空间,即地址按照固定大小的单元编址(byte,当然理论上也可以是word,只要大小是一样的),并且地址从0,1,2,3..依次递增,到达某个上限n构成的地址空间;和非线性的地址空间,目前见过的只有X86的分段式地址空间,地址是由“段基值”和“段内偏移”两部分组成。而所谓的线性地址,是指线性地址空间中的地址。这个线性地址空间可能是power的物理地址空间,也可能是虚拟地址空间。

在当前的linux地址空间中,没有“segmentation”这个概念。这个是分段,在操作系统中讨论虚拟地址的时候有段式的,页式的和段页式的。而linux使用的是页式的虚拟地址空间管理,用的是二级页表。在x86上,处理器有的物理地址空间有分段的概念,但是linux进入保护模式后并不使用这个概念,或则说,linux只用x86的一个段,所有的物理地址都在这个段中。在linux中,实现的虚拟地址空间就是一个线性地址空间,地址从0到2的32次幂减1.在powerpc上,处理器和操作系统都没有分段的概念。

paging,当说一个地址空间是paging的时候,是指这个地址空间被分成了等大的页框(page frame),每次分配空间的时候都以一个页框的大小为单位分配,比如现在的linux操作系统用4096byte作为页框的大小。同样,所有的数据或是代码也分成了同样大小的块,叫做页面。页面内的东西必须是连续的,而页面之间的就不一定了。这是一种存储管理方法。
当说page out或page in的时候,指将一个页面的数据从内存导入磁盘,或是从磁盘导入内存。
在MMU中,不进行paging。它只是根据一个CPU发出的有效地址或称虚拟地址,去查找页表,转换成物理地址。

mov ax, [1234] <--------->这个只是x86的一种寻址模式
-----------------------
[1234] 就是有效地址形式,若ds:f000,dos 下经过 segmentation 后,就是 f1234,这个地址就是 linear address (vritual)  <------------------------------> 在dos下没有虚拟地址的概念,
                                       因为Dos并不启用MMU。Dos也不实现虚拟地址空间
                                       而且这个对于CPU而言也不能
                                       叫做线性地址,因为这时候的地址空间是分段式的。
                                      
当然,此时的 linear address 就是 physical address。

逻辑地址的确如你所说,这个概念只有在x86上有。
保护模式就是所说的操作系统为进程使用虚拟地址空间的模式,在这种模式下启用MMU


版主,我觉得我们的主要分歧在于这些概念的定义上。很可能是看的书的翻译不大一样。如果方便的话,请说一下你看的《微机原理》、《操作系统》、《体系结构》是哪三本书?
我上面的概念来自于王克义的《微机原理》(北大出版社)、陈向群的《操作系统》(北大出版社)和《Computer Design & Orgnization Software/hardware interface》(影印版)。前两本书应该还有别的作者,只是时间长了,有些记不清。








原帖由 mik 于 2008-9-1 23:49 发表


effecitive address 和 virtual address 是不同的,无论是从概念上讲,还是软件层来讲,或是指令层来讲。

effecitive address 是地址形式是:,是指令层面上地址元素。是最原始的。

virtual address  ...

[ 本帖最后由 freearth 于 2008-9-2 00:59 编辑 ]
作者: cjaizss    时间: 2008-09-02 09:25
我也觉得effective address是[base+index*scale+disp]的结果,而非本身,[base+index*scale+disp]这种寻址方式是X86的寻址方式。CISC可能支持这种较为复杂的寻址方式,而RISC则可能不会支持,它们支持的寻址模式相对少。另外,MMU是可配置的,然而一般都是在内核层次上,而应用程序层次上,地址转换不可见。
作者: mik    时间: 2008-09-02 22:48
原帖由 freearth 于 2008-9-2 00:55 发表
“,是指令层面上地址元素。是最原始的”
我记得这个是指令系统体系结构中的“寻址模式”而不能叫做有效地址。比如,
lea r,
你是把“”计算出来的值放入了寄存器中,这个值是一个数字,二进制无符号数,这 ...


你这样就颠倒概念了,本来 effecitive address 这个概念只有 x86 上才有的,怎么扯上 power 上去了。
你看了这么多《微机原理》这类书籍,有些东西根深蒂固,我也不打算去说服你。

我不看国内的《微机原理》之类的书籍,我只会看 AMD & Intel 官方的文档及 Addison-Wesley 的 System Architecture 系列的书籍
且我推荐看这些权威的书籍,其它什么微机原理相比已经没什么价值了。
在<computer orgranization & design>一书也没找到你这些概念。

说回正题:

>> 我记得这个是指令系统体系结构中的“寻址模式”而不能叫做有效地址。比如,

在这里你又混淆了,“寻址模式”是“寻址模式”,与“有效地址”完全是两个概念
寻址模式是指出寻找数据的方式,它是一个寻找数据方法上的一个概念。
有效地址是内存地址上的一个概念,完全两码事。


mov eax, 1         --->  这个数据的“寻址模式”就是:立即数寻址。
mov eax, ebx     ---->   这个数据的“寻址模式”就是:寄存器寻址。

[base + index * scale + disp]:这是一个内存寻址模式,数据在内存里,它是 x86 的最复杂的一个寻址模式,可以转化为几种形式:
[eax];  [eax+ebx*2+0xc];  [0x11223344] 等寻址方式。 无论以何种寻址方式得出的是一个“有效地址”。




>> 在当前的linux地址空间中,没有“segmentation”这个概念。

你这个概念非常的错误!!! 说明你根本不了解“保护模式”,我建议你仔细地了解“保护模式”, linux 只是用了平坦的内存方式。没有"segmentation"这个概念,selector 是什么? GDT 是什么?
在x86上,任何操作系统都逃不过 segmentation,除非不是 x86,即使在 x64 上,还是没完全逃脱 segmentation


>>  在dos下没有虚拟地址的概念, 因为Dos并不启用MMU。Dos也不实现虚拟地址空间,而且这个对于CPU而言也不能
    叫做线性地址,因为这时候的地址空间是分段式的。

机器就是机器,哪管你在什么模式下,这是一个物理构造上。 真得很诚心的建议你深入学习 x86。


开始还认为你基础不错,看来不是这样的!

最后,上个图你看看:

作者: zx_wing    时间: 2008-09-02 23:02
牛!花这么多时间讨论自己知道的东西。
作者: mik    时间: 2008-09-02 23:11
原帖由 zx_wing 于 2008-9-2 23:02 发表
牛!花这么多时间讨论自己知道的东西。


作者: freearth    时间: 2008-09-03 00:11
标题: 回复 #9 mik 的帖子
看来的确我的基础比较差,我没有给x86维护过编译器和kernel的代码。我做的事情都是基于power和另外一种RISC的处理器的。Power上也有有效地址的概念,这个不是x86才有的。

你的图中有段表GDT,对的,这是x86 CPU启用保护模式必须的,而且在linux下,这个表中应该有四个表项,本别对应于user code, user data, kernel code, kernel data。这四个表项的base都是0x00000000,而且,内核启动之后,这个表是不会改的。正如我在7楼所说,“linux只使用了x86的一个段”,在虚存管理中,只使用分页的概念。之所以必须设置这个段表,是因为你不设置,x86不工作。如果要说使用了分段,那只是形式上的,事实上不使用。

机器就是机器,哪管你在什么模式下,这是一个物理构造上
Dos在X86上没有虚拟地址空间。这个地址空间只有CPU是做不出来的。所有不启用MMU的操作系统,都不会有虚拟地址空间。在6楼中你认为,经过x86的段表之后的地址就是虚拟地址,在Dos中,那个地址绝对不能叫虚拟地址。

至少根据我的理解,你在9楼的关于有效地址和寻址模式的解释和我在7楼的解释一致,与你在6楼的解释矛盾。

[ 本帖最后由 freearth 于 2008-9-3 00:31 编辑 ]
作者: cjaizss    时间: 2008-09-03 00:50
原帖由 mik 于 2008-9-2 22:48 发表


你这样就颠倒概念了,本来 effecitive address 这个概念只有 x86 上才有的,怎么扯上 power 上去了。
你看了这么多《微机原理》这类书籍,有些东西根深蒂固,我也不打算去说服你。

我不看国内的《微机 ...

对于这张图,我还是把原书中的相关内容应用一下,以便理解。
The memory management facilities of the IA-32 architecture are divided into two

parts: segmentation and paging. Segmentation provides a mechanism of isolating

individual code, data, and stack modules so that multiple programs (or tasks) can

run on the same processor without interfering with one another. Paging provides a

mechanism for implementing a conventional demand-paged, virtual-memory system

where sections of a program’s execution environment are mapped into physical

memory as needed. Paging can also be used to provide isolation between multiple

tasks. When operating in protected mode, some form of segmentation must be used.

There is no mode bit to disable segmentation. The use of paging, however, is

optional.

These two mechanisms (segmentation and paging) can be configured to support

simple single-program (or single-task) systems, multitasking systems, or multipleprocessor

systems that used shared memory.


As shown in Figure 3-1, segmentation provides a mechanism for dividing the

processor’s addressable memory space (called the linear address space) into

smaller protected address spaces called segments. Segments can be used to hold

the code, data, and stack for a program or to hold system data structures (such as a

TSS or LDT). If more than one program (or task) is running on a processor, each

program can be assigned its own set of segments. The processor then enforces the

boundaries between these segments and insures that one program does not interfere

with the execution of another program by writing into the other program’s segments.

The segmentation mechanism also allows typing of segments so that the operations

that may be performed on a particular type of segment can be restricted.

All the segments in a system are contained in the processor’s linear address space.

To locate a byte in a particular segment, a logical address (also called a far pointer)

must be provided. A logical address consists of a segment selector and an offset. The

segment selector is a unique identifier for a segment. Among other things it provides

an offset into a descriptor table (such as the global descriptor table, GDT) to a data

structure called a segment descriptor. Each segment has a segment descriptor, which

specifies the size of the segment, the access rights and privilege level for the segment, the segment type, and the l
ocation of the first byte of the segment in the

linear address space (called the base address of the segment). The offset part of the

logical address is added to the base address for the segment to locate a byte within

the segment. The base address plus the offset thus forms a linear address in the

processor’s linear address space.

If paging is not used, the linear address space of the processor is mapped directly

into the physical address space of processor. The physical address space is defined as

the range of addresses that the processor can generate on its address bus.

Because multitasking computing systems commonly define a linear address space

much larger than it is economically feasible to contain all at once in physical memory,

some method of “virtualizing” the linear address space is needed. This virtualization

of the linear address space is handled through the processor’s paging mechanism.

Paging supports a “virtual memory” environment where a large linear address space

is simulated with a small amount of physical memory (RAM and ROM) and some disk storage. When using paging,

each segment is divided into pages (typically 4 KBytes

each in size), which are stored either in physical memory or on the disk. The operating

system or executive maintains a page directory and a set of page tables to keep

track of the pages. When a program (or task) attempts to access an address location

in the linear address space, the processor uses the page directory and page tables to

translate the linear address into a physical address and then performs the requested

operation (read or write) on the memory location.

If the page being accessed is not currently in physical memory, the processor interrupts

execution of the program (by generating a page-fault exception). The operating

system or executive then reads the page into physical memory from the disk

and continues executing the program.

When paging is implemented properly in the operating-system or executive, the

swapping of pages between physical memory and the disk is transparent to the

correct execution of a program. Even programs written for 16-bit IA-32 processors

can be paged (transparently) when they are run in virtual-8086 mode.

[ 本帖最后由 cjaizss 于 2008-9-3 01:01 编辑 ]
作者: freearth    时间: 2008-09-03 09:09
我发现,我在说分段、分页的时候,是从操作系统角度来看的。比如我说,linux不用分段的机制,因为linux操作系统的虚存管理用的是三级页表(其实在PC上中间一级占0bit,所以事实上是两级)的页式存储管理。当linux启动的时候设置了X86的GDT之后,在整个操作系统的运行过程中,linux都不再使用分段的概念。当操作系统从程序中拿出来一个32位的地址之后,linux就认为这个是虚拟地址了。
相信看过linux代码的人都会有这个印象:linux的虚拟地址分为四个部分,分别是
[PGD][PMD][PTE][OFFSET]吧,而且,在PC上,PMD的长度是0。
事实上,X86的硬件必须用它的段,linux为了能够用x86的保护模式,只好在启动的时候将GDT的表项的基值设置为0,这样,当linux将自己认为的虚拟地址发出的时候,还是会被硬件自动的加上0。而硬件却认为,加了0之后的地址才是虚拟地址。
再比如说,我说在操作系统支持虚拟地址的时候,程序员使用的地址就是虚拟地址。用objdump看一个二进制代码,里面打出来的地址,和linux认为的虚拟地址是一致的。当程序执行的时候,用得也是那些地址,而这些地址总是会被CPU自动地加上0。

而版主在说的时候,总是直接用处理器来说,认为只要经过X86的段逻辑之后,得到的地址就是虚拟地址。

我一开始的时候确实犯了一个错误。我在讨论虚拟地址的时候,没有用X86的机器模型来讨论。以至于当版主说虚拟地址是MMU产生的时候,立刻就予以反驳。从这张图看来,X86用的虚拟地址,的确是由硬件产生的。

习惯上,我在一般讨论问题的时候,大脑里面想的机器模型总是一个类似MIPS处理器的模型,而使用的操作系统模型就是linux。呵呵,看来这个习惯要改了,马上就要工作了,要开始用产业界的习惯了。

原帖由 cjaizss 于 2008-9-3 00:50 发表

对于这张图,我还是把原书中的相关内容应用一下,以便理解。
The memory management facilities of the IA-32 architecture are divided into two

parts: segmentation and paging. Segmentation provide ...

[ 本帖最后由 freearth 于 2008-9-3 09:32 编辑 ]
作者: 耿耿于怀    时间: 2008-09-04 22:09
lz说的是什么呢??
作者: prolj    时间: 2008-09-04 22:38
标题: 回复 #15 耿耿于怀 的帖子
lea啊,load effecitve address
作者: prc    时间: 2008-09-05 14:07
Virtual Address: 以 segmentffset 形式表示的地址。在X86架构下,segment是隐含的,比如访问数据会硬件会自动加上ds段的偏移;IP则自动加上cs段的偏移。
Linear Address: segment base加上offset之后得到的地址。
physical address: Linear Address经过硬件MMU转换之后的地址,也就是bus地址。

但是在windows/linux下,所有段的基地址都为0,所以对于软件开发者来说,看到的效果就是virtual address = linear address




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2