扫盲篇:(熟手可跳过,直接查看正文篇) 一、什么叫寻址空间? 寻址空间一般指的是CPU对于内存寻址的能力。通俗地说,就是能最多用到多少内存的一个问题。数据在存储器(RAM)中存放是有规律的 ,CPU在运算的时候需要把数据提取出来就需要知道数据在那里 ,这时候就需要挨家挨户的找,这就叫做寻址,但如果地址太多超出了CPU的能力范围,CPU就无法找到数据了。 CPU最大能查找多大范围的地址叫做寻址能力 ,CPU的寻址能力以字节为单位。 通常人们认为,内存容量越大,处理数据的能力也就越强,但内存容量不可能无限的大,它要受到系统结构、硬件设计、制造成本等多方面因素的制约,一个最直接的因素取决于系统的地址总线的地址寄存器的宽度(位数)。 计算机的寻找范围由总线宽度(处理器的地址总线的位数)决定的,也可以理解为cpu寄存器位数,这二者一般是匹配的。
Intel公司早期的CPU产品的地址总线和地址寄存器的宽度为20位,即CPU的寻址能力为2^20=1024*1024字节=1024K字节=1M字节;286的地址总线和地址寄存器的宽度为24位,CPU的寻址能力为2^24=1024*4*1024*4B=4*1024*4KB=16M;386及386以上的地址总线和地址寄存器的宽度为32位,CPU的寻址能力为2^32=4096M字节=4G字节。 也就是说,如果机器的CPU过早,即使有很大的内存也不能得到利用,而对于现在的PⅡ级的CPU,其寻址能力已远远超过目前的内存容量。 由此推出:地址总线为N位(N通常都是8的整数倍;也说N根数据总线)的CPU寻址范围是2的N次方字节,即2^N(B)。
二、16位、32位、64位通常指的是什么? 从CPU的发展史来看,从以前的8位到现在的64位,8位也就是CPU在一个时钟周期内可并行处理8位二进字符0或是1,那么16就以此类推是64位就64位二进制.
从数据计算上来讲理论上64位比32快一半。但因为电脑是软硬相配合才能发挥最佳性能的.所以操作系统也必须从32位的到64位的,而且系统的硬件驱动也必须是64位的.
在64CPU的计算机上要安装64位操作系统64位的硬件驱动,32位的硬件驱动是不能用的,只有这样才能发挥计算机的最佳性能.如果64CPU装32操作系统的话,那性能不会有明显的提升。
三、为什么是2的N次方,而不是其他数的N次方?
因为计算机是采用二进制计算的。 假设一台计算机,它只有1根地址线,请问它最多能对几个存储单元寻址?答案是:2个.因为在任何2进制计算机中,所有物理元件只有 0,1两种状态,对应这个例子,我们假设已经把这唯一的一根地址线与两个存储单元a和b连上了,那么究竟怎么确定何时读a何时读b?有一个办法,当地址线上的电压是高电压时我们读a,相反是低电压时,我们读b.如此一来,一根地址线的情况下,只能对2个存储单元进行寻址 依次类推,2根地址线时可以对4个存储单元进行寻址,对应的电压情况可以是:低低,低高,高低,高高;继续想下去,3根地址线就可以对8个存储单元进行寻址(3个1和3个0不同组合情况:111、110、100、000、101、100、001、011),4根就是16个,也就是说,当有n根地址线时,可以对2的n次方个存储单元进行寻址。
一根线是怎么连接到两个存储单元的?好像不同于一根电话线吧,他有两个线芯或才网线,有八个小线(线芯)?
四、什么是存储单元?
存储单元一般应具有存储数据和读写数据的功能,一般以8位二进制作为一个存储单元,也就是一个字节。每个单元有一个地址,是一个整数编码,可以表示为二进制整数。程序中的变量和主存储器的存储单元相对应。变量的名字对应着存储单元的地址,变量内容对应着单元所存储的数据。
五、为什么计算机采用二进制?
(1)技术实现简单,计算机是由逻辑电路组成,逻辑电路通常只有两个状态,开关的接通与断开,这两种状态正好可以用“1”和“0”表示。 (2)简化运算规则:两个二进制数和、积运算组合各有三种,运算规则简单,有利于简化计算机内部结构,提高运算速度。 (3)适合逻辑运算:逻辑代数是逻辑运算的理论依据,二进制只有两个数码,正好与逻辑代数中的“真”和“假”相吻合。 (4)易于进行转换,二进制与十进制数易于互相转换。 (5)用二进制表示数据具有抗干扰能力强,可靠性高等优点。因为每位数据只有高低两个状态,当受到一定程度的干扰时,仍能可靠地分辨出它是高还是低。
正文篇(本文篇幅较长,内容相对生涩,欢迎收藏,或者加入微信群讨论,加z00143104微信,申请加群)
[url=][/url]
我们的宇宙诞生于137亿年前的一次大爆炸。在宇宙之外的一个宇宙中,有一个星系与银河系具有非常显著的相似之处,在这个星系的一条旋臂上,存在着一个恒星系统,这个系统中只有一颗恒星,这颗恒星也与我们的太阳非常相似,再将镜头放大,在这颗恒星周围存在着八大行星,其中第三颗行星与我们的地球非常相似,这颗行星上同样也存在着高等直立智慧生物,其中有一个生物和您非常相似,过着同样的生活,更重要的是,此时此刻,他与您一样,也正在阅读这篇文章正文第一段的最后一行。 在X86系统里面,其实有多个寻址空间(Memory空间、IO空间、PCI的配置空间)类似于独立的多个并行的宇宙,虽然没有多宇宙的相似性,但是每个空间通过自己的指令,自己独立编制,是不同的空间,互不干涉。这在RISC处理器的编址方式里面,是不涉及的,在RISC处理器中,一般所有的外设,内存,寄存器都在统一的寻址空间。 IO空间 通过in/ins、out/outs指令访问。
16位地址范围(0-0FFFFh)。
对于x86架构来说,通过IN/OUT指令访问。PC架构一共有65536个8bit的I/O端口,组成64KI/O地址空间,编号从0~0xFFFF。连续两个8bit的端口可以组成一个16bit的端口,连续4个组成一个32bit的端口。I/O地址空间和CPU的物理地址空间是两个不同的概念,例如I/O地址空间为64K,一个32bit的CPU物理地址空间是4G。
MMIO占用CPU的物理地址空间,对它的访问可以使用CPU访问内存的指令进行。一个形象的比喻是把文件用mmap()后,可以像访问内存一样访问文件、同样,MMIO是用访问内存一样的方式访问I/O资源,如设备上的内存。MMIO不能被cache,原因以前很多帖子论述过,就不多说了(有特殊情况,如VGA)。
Port I/O和MMIO的主要区别在于:
1)前者不占用CPU的物理地址空间,后者占有(这是对x86架构说的,一些架构,如IA64,port I/O占用物理地址空间)。
2)前者是顺序访问。也就是说在一条I/O指令完成前,下一条指令不会执行。例如通过Port I/O对设备发起了操作,造成了设备寄存器状态变化,这个变化在下一条指令执行前生效。uncache的MMIO通过uncahce memory的特性保证顺序性。
3)使用方式不同
由于port I/O有独立的64KI/O地址空间,但CPU的地址线只有一套,所以必须区分地址属于物理地址空间还是I/O地址空间。早期的CPU有一个M/I针脚来表示当前地址的类型。
Memory空间 通过mov指令以及其他相关指令访问。
访问空间与CPU模式有关。
后面章节做详细描述。 PCI Config 空间 PCI设备的配置寄存器空间•每个设备256个寄存器(00-FFh)•X86平台通过CF8/CFC端口访问。
这一段PCI的内容,其实在RISC处理器中,带PCI或者PCIe外设的处理器,一样存在PCI配置空间的问题。 后续,有PCI系统学习的内容,再做详细描述。本文不做展开描述。
X86内存地址空间 说明: S16 表示 16 位段寄存器 P16 表示 16 位的普通寄存器, 立即数, 结果为 16 位的表达式等等. P32 同上, 只是扩展到 32 位. 一. CPU 数据线和地址线的概况 1. 8086: 8 位数据线, 16 位地址线. 8 位数据线和前8位地址线合用. 2. 8088: 16位数据线, 16位地址线. 数据线和地址线完全分时合用. 3. 80186: 16位数据线, 16位地址线. 数据线和地址线完全分时合用. 4: 80188: 16位数据线, 16位地址线. 数据线和地址线完全分时合用. 5. 80286: 16位数据线, 24位地址线. 数据线和地址线是完全分开的. 转到保护模式的过渡 CPU. 6. 80386: 32位数据线, 32位地址线. 数据线和地址线是完全分开的(其中80386SX像80286). 7. 80486: 32位数据线, 32位地址线. 8. Pentium: 64位数据线, 32位地址线. 9. Pentium Pro: 64位数据线, 36位地址线. 二. 实模式: 分段内存 1. 支持的 CPU: 8086 以上 2. 启用方式: 启动后自动进入 3. 地址长度: 20 4. 寻址能力: 1M 5. ALU宽度: 16 6. 寻址过程: 引入了 CS, DS, SS, ES 这 4 个 16 位的段寄存器. 寻址时将段寄存器左移 4 位后再加上 16 位的偏移, 既: (S16 << 4) + P16. 得到 20 位的地址. 省略段寄存器时, 会使用默认的段寄存器: 段 | 偏移 | 用途 | CS | IP | 指令地址 | DS | AX, BX, SI, DI, Disp8/16 | 数据地址 | SS | SP, BP | 堆栈地址 | ES | DI | 串操作目的地址 |
l只能寻址1MB以下内存。源于8086CPU的20根地址线设计。
l内存寻址由段地址和偏移地址组成。
l一个段包含64KB空间的内存。段地址和偏移地址寄存器皆为16bit。
l没有数据保护功能。
l段地址是16Byte对齐,因此事实上不同的段是可以重叠的。
三. 保护模式: 分段内存
1. 支持的 CPU: 80286 以上 2. 启用方式: 将 CR0 寄存器的 PE 位置 1. 3. 地址长度: 32 4. 寻址能力: 4GB 5. ALU宽度: 32 6. 寻址过程: 从 32 位的数据宽度, 寻 32 位的地址, 看起来似乎是非常简单的一件事情. 不过由于对内存保护的加入, 这个过程其实更为复杂. 而 Intel 又选择了兼容之前的分段内存, 且分段机制在进入保护模式后是必须的, 不能关闭. 其实大多数的操作系统实现的时候都选择绕过分段机制, 只使用分页机制来进行内存管理. 保护模式的分段机制保留了以前的段寄存器, 并且增加了两个 FS, GS. 这些段寄存器仍然为 16 位, 但是里面保存的不再是段的基地址了, 而是一个段选择子。
同样, 在没有指明段寄存器的情况下, 会使用一个默认的段寄存器: 段 | 偏移 | 用途 | CS | EIP | 指令地址 | DS | EAX, EBX, ECX, EDX, ESI, EDI, Disp8/16/32 | 数据地址 | SS | ESP, EBP | 堆栈地址 | ES | EDI | 串操作目的地址 | GS | 无 | 一般地址 | FS | 无 | 一般地址 |
l可以寻址4GB空间。l每个段使用一个段描述符定义。每个段描述符长度8byte。l段主要属性:起始地址,size,Code/Data,方向,特权级,粒度等。
l段具有范围保护功能,只能寻址段范围内的指令和数据,超出段范围将引起CPU异常错误。
l程序、数据的引用地址皆为相对于段的起始地址的偏移量。这使程序可以定位在实际内存中的任意位置。
l相关寄存器:GDTR、LDTR、IDTR、TRlCS、DS、ES、SS等保存的是“段选择字”,而非段的地址。
四. 保护模式: 分页内存 1. 支持的 CPU: 80386 以上, PSE 需要 Pentium 以上 2. 启用方式: 将 CR0 寄存器的 PG 位置 1 3. 地址长度: 32 4. 寻址能力: 4GB 5. ALU宽度: 32 6. 寻址过程: 分页机制是现代操作系统实现内存管理的主要方式. 它将线性地址空间划分为固定大小的页面, 每个页面可以被映射到物理内存或外部存储器的虚拟内存文件中, 并且进行权限检查. 在没有启用 PAE 时, 内存页面大小可以是 4KB 或 4MB. 如果 CR4 中的 PSE 位是 0, 则只支持 4KB 的内存页. 如果 PSE 位是 1, 则根据 PDE 中的 PS 位来决定内存页的大小. 1# 4KB 页面寻址 对于 4KB 的页面, 32 位的线性地址不再表示物理地址。 2# 4MB 页面寻址 (PSE 模式) 对于 4MB 的页面, 不需要使用页表, 只需要页目录的一层映射. 要配置 4MB 的页面, 需要设置 CR4 中的 PSE 位. 并在 PDE 中设置 PS 位.
1. 内存的二级分页结构
五. 虚拟 86 模式 (V8086, V86) 1. 支持的 CPU: 80386 以上 2. 启用方式: 在保护模式下, 将标志寄存器中的 VM 位置 1 3. 地址长度: 20 4. 寻址能力: 1MB 5. ALU 宽度: 16 6. 寻址过程: 虚拟 86 模式是保护模式下, 某些任务的一种工作模式. 此模式是为了能够在保护模式下运行实模式软件. 在虚拟 86 模式下, 软件的工作环境和实模式类似, 使用 (S16 << 4) + P16 的方式访问 1M 的内存, 但是得到的地址不再是物理地址了, 而是由系统的虚拟 86 管理程序分配的内存. 虚拟 86 模式下也可以使用内存分页(实模式下不行), 让没有使用的内存空间不占用物理内存. 虚拟 86 模式下的中断和特殊指令的访问也由系统软件进行模拟, 不能直接访问硬件. 在虚拟 86 模式下, 是不能直接更改标志寄存器的 VM 位的, 所以进入和退出虚拟 86 模式是通过任务切换或中断来完成的. 1. 保护模式和 V86 模式的切换
六. PSE-36: Page Size Extension 36
1. 支持的 CPU: Pentium III 以上 (另说为 Pentium II) 2. 启用方式: 开启 PSE 的情况下, 如果 CPU 支持即可使用 3. 地址长度: 36 4. 寻址能力: 64GB 5. ALU 宽度: 32 6. 寻址过程: 在前面的分页内存中, 处于 PSE 模式时, PDE 结构只使用了高 10 位作为基址. 在 PSE-36 模式里, 将使用其中的 14 位来作为基址, 这样, 最后的地址位数将达到 36 位, 寻址能力提高到 64GB. 在 PSE 36 模式下, 4MB 页面的 PDE 结构变为: 对于 4KB 的页面, 仍然和普通的分页内存相同, 它可以表示的内存仍然只要 4GB. 所以, 在 PSE 36 模式下, 4KB 的页面只能位于前 4GB 物理内存中. 4GB 以上的内存只能通过 PSE 方式访问, 页面大小只能为 4MB.
七. PAE: Physical Address Extension 物理地址扩展 1. 支持的 CPU: Pentium Pro 以上 2. 启用方式: 设置 CR4 中的 PAE 位 3. 地址长度: 36 4. 寻址能力: 64GB 5. ALU 宽度: 32 6. 寻址过程: 在 PAE 模式中, 应用程序仍然为 32 位, 只能使用 4GB 的内存空间. 但是系统可以把不同的进程映射到 64GB 的物理内存中. 应用程序如果需要使用大于 4GB 的内存, 则需要操作系统的特殊支持(Windows 为 AWE, Address Windowing Extensions; Unix 存在多种, 比如 mmap ). 启用 PAE 后, CR3 寄存器不再指向页目录基址, 而是指向一个页目录指针表 PDPT (Page Directory Pointer Table), 即包含 4 个页目录指针的表. 页目录项和页表项从原来的 4 字节变为 8 字节, 占用的内存大小仍然为 4KB, 所以其中的表项从 1024 个变为 512 个. 因此, 现在一共有 4 个页目录表, 页目录表和页表的下标也只需要 9 位了, 于是线性地址的划分也有了变化. 八. 长模式 (long-mode, IA-32e 模式) 1. 支持的 CPU: x86-64 的 CPU 2. 启用方式: 同时满足以下条件: (1). 开启保护模式 CR0.PE = 1 (2). 开启分页机制 CR0.PG = 1 (3). 开启 PAE CR4.PAE = 1 (4). IA32_EFER.LME = 1 (Long Mode Enable) (5). IA32_EFER.LMA = 1 (Long Mode Active) 3. 地址长度: 48 4. 寻址能力: 256 TB 5. ALU 宽度: 64 6. 寻址过程: x86-64 体系, 也被称为 x64 体系, 还被叫做 AMD 64 和 Intel 64 体系. 他们是 x86 体系向 64 位的扩展, 有别于纯 64 位架构的 IA64 体系. x64 体系兼容 x86 的运行模式, 并增加一种新的长模式. x64 的运行模式如下: x64 体系 | 子模式 | 资源 | long-mode (IA-32e) | 64-bit mode | 64 位执行环境 | compatibility mode | 内核为 64 位, 应用为 32 位的 legacy mode | legacy mode | protected mode | 32 位 | real mode | 16 位 |
在长模式下, 内核只能为 64 位, 应用可以为 64 位或 32 位. 兼容模式(compatibility mode)和保护模式基本相同. 在 64 位模式下, 寄存器被扩展为 64 位, 默认的地址大小也是 64 位(可以使用 67H 前缀来使用 32 位地址, 但是不能使用 16 位地址), 并增加了 RIP 相对寻址方式. 兼容模式下代码段描述符中的 D 标志位决定了默认的地址大小: D = 0 默认为16位地址, D = 1 默认为32位地址, 可通过 67H 前缀来改变默认值. 虚拟地址空间当处理器读或写入内存位置时,它会使用虚拟地址。作为读或写操作的一部分,处理器将虚拟地址转换为物理地址。通过虚拟地址访问内存有以下优势: 程序可以使用一系列相邻的虚拟地址来访问物理内存中不相邻的大内存缓冲区。 程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为 4 KB)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动。 不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程使用的物理内存。
进程可用的虚拟地址范围称为该进程的“虚拟地址空间”。每个用户模式进程都有其各自的专用虚拟地址空间。 对于 32 位进程,虚拟地址空间通常为 2 GB,范围从 0x00000000 至 0x7FFFFFFF。对于 64 位进程,虚拟地址空间为 8 TB,范围从 0x000'00000000 至 0x7FF'FFFFFFFF。一系列虚拟地址有时称为一系列“虚拟内存”。 此图说明了虚拟地址空间的一些重要功能。
该图显示了两个 64 位进程的虚拟地址空间:Notepad.exe 和 MyApp.exe。每个进程都有其各自的虚拟地址空间,范围从 0x000'0000000 至 0x7FF'FFFFFFFF。每个阴影框都表示虚拟内存或物理内存的一个页面(大小为 4 KB)。注意,Notepad 进程使用从 0x7F7'93950000 开始的虚拟地址的三个相邻页面。但虚拟地址的这三个相邻页面会映射到物理内存中的非相邻页面。而且还注意,两个进程都使用从 0x7F7'93950000 开始的虚拟内存页面,但这些虚拟页面都映射到物理内存的不同页面。 用户空间和系统空间诸如 Notepad.exe 和 MyApp.exe 的进程在用户模式下运行。核心操作系统组件和多个驱动程序在更有特权的内核模式下运行。有关处理器模式的详细信息,请参阅[url=]用户模式和内核模式[/url]。每个用户模式进程都有其各自的专用虚拟地址空间,但在内核模式下运行的所有代码都共享称为“系统空间”的单个虚拟地址空间。当前用户模式进程的虚拟地址空间称为“用户空间”。 在 32 位 Windows 中,可用的虚拟地址空间共计为 2^32 字节(4 GB)。通常较下的 2 GB 用于用户空间,较上的 2 GB 用于系统空间。
在 32 位 Windows 中,你可以指定(在启动时)超过 2 GB 用于用户空间。结果是系统空间可用的虚拟地址更少。可以将用户空间的大小增至 3 GB,在这种情形下系统空间仅有 1 GB。若要增大用户空间的大小,请使用 [url=]BCDEdit /set increaseuserva[/url]。 在 64 位 Windows 中,虚拟地址空间的理论大小为 2^64 字节(16 百亿亿字节),但实际上仅使用 16 百亿亿字节范围的一小部分。范围从 0x000'00000000 至 0x7FF'FFFFFFFF 的 8 TB 用于用户空间,范围从 0xFFFF0800'00000000 至 0xFFFFFFFF'FFFFFFFF 的 248 TB 的部分用于系统空间。 用户模式下运行的代码可以访问用户空间,但不能访问系统空间。此限制可防止用户模式代码读或更改受保护的操作系统数据结构。内核模式下运行的代码既可以访问用户空间,也可以访问系统空间。即,在内核模式下运行的代码可以访问系统空间和当前用户模式进程的虚拟地址空间。 在内核模式下运行的驱动程序必须在直接从用户空间地址中读取或写入这些地址时非常小心。此方案说明了原因。 用户模式程序发起从设备读取某些数据的请求。程序提供缓冲区的起始地址以接收数据。 在内核模式下运行的设备驱动程序例程启动读取操作并将控制权返回到其调用程序。 然后,设备中断了当前运行的任何线程以显示读取操作完成。 中断由在此任意线程上运行的内核模式驱动程序例程进行处理,该例程属于任意进程。 此时,驱动程序不得将数据写入用户模式程序在步骤 1 中提供的开始地址。此地址位于发起请求的进程的虚拟地址空间,该进程可能很大程度上不同于当前进程。
页面缓冲池和非页面缓冲池在用户空间中,所有物理内存页面都可以根据需要进行分页至磁盘文件。在系统空间中,某些物理页面可以分页,而其他页面不能。系统空间具有用于动态分配内存的两个区域:页面缓冲池和非页面缓冲池。在 64 位 Windows 中,页面缓冲池为 128 GB 的虚拟地址,范围从 0xFFFFA800'00000000 至 0xFFFFA81F'FFFFFFFF。非页面缓冲池为 128 GB 的虚拟地址,范围从 0xFFFFAC00'00000000 至 0xFFFFAC1F'FFFFFFFF。 在页面缓存池中分配的内存可以根据需要分页至磁盘文件。在非页面缓冲池中分配的内存永远无法分页至磁盘文件。
Flat Mode 平坦模式
所有段包含整个4G空间;可以寻址4G范围。
可以理解为保护模式的特殊情况,以进入保护模式的方式进入。
内存访问模式切换
ARM地址空间分配
1、ARM,32位的,寻址4GB空间,内存(SDRAM)和端口(特殊寄存器),还有ROM都映射到同一个4G空间里. 2:一般都用SDRAM做内存flash(nor、nand)来当做ROM。其中nand flash没有地址线,一次至少要读一页(512B).其他两个有地址线 3:norflash不用来运行代码,只用来存储代码,NORflash,SDRAM可以直接运行代码) 4:s3c2440总共有8个内存banks 6个内存bank可以当作ROM或者SRAM来使用 留下的2个bank除了当作ROM 或者SRAM,还可以用SDRAM(各种内存的读写方式不一样) 7个bank的起始地址是固定的 还有一个灵活的bank的内存地址,并且bank大小也可以改变
5、FLASH启动,有两种模式:NAND和非NAND(这里是nor flash)。 具体采用的方式取决于OM0、OM1两个引脚 OM[1:0]所决定的启动方式 OM[1:0]=00时,处理器从NAND Flash启动 OM[1:0]=01时,处理器从16位宽度的ROM启动 OM[1:0]=10时,处理器从32位宽度的ROM启动。 OM[1:0]=11时,处理器从Test Mode启动。
Arm的启动都是从0地址开始,所不同的是地址的映射不一样。在arm开电的时候,要想让arm知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候arm会通过引脚的电平来判断。 1当引脚OM0跟OM1有一个是高电平时,这时地址0会映射到外部nGCS0片选的空间,也就是Norflash,程序就会从Norflash中启动,arm直接取Norflash中的指令运行。 2当OM0跟OM1都为低电平,则0地址内部bootbuf(一段4k的SRAM)开始。系统上电,arm会自动把NANDflash中的前4K内容考到bootbuf(也就是0地址),然后从0地址运行。 这时NANDFlash中的前4K就是启动代码(他的功能就是初始化硬件然后在把NANDFlash中的代码复制到RAM中,再把相应的指针指向该运行的地方) 为什么会有这两种启动方式,关键还是两种flash的不同特点造成,NOR FLASH容量小,速度快,稳定性好,输入地址,然后给出读写信号即可从数据口得到数据,适合做程序存储器。NAND FLASH 总容量大,但是读写都需要复杂的时序,更适合做数据存储器。这种不同就造成了NORflash可以直接连接到arm的总线并且可以运行程序,而NANDflash必须搬移到内存(SDRAM)中运行。 在实际的开发中,一般可以把bootloader烧入到Norflash,程序运行可以通过串口交互,进行一定的操作,比如下载,调试。这样就很可以很方便的调试你的一些代码。Norflash中的Bootloader还可以烧录内核到Norflash等等功能。
arm寻址方式 1. 立即数寻址 这是一种比较简单的寻址方式,操作数包含在指令当中。取出指令,即取出了操作数。对应的寻址方式也就叫做立即数寻址。 例: ;注意arm汇编中,指令不能顶格写,在前面加空格。 ;而定义变量的时候,必须顶格写,这里新手要注意。 ADD R0,R0,#1 ;R0 <==R0 +1 ,把R0的内容加1。 ADD R0,R0,#0x30 ;R0 <==R0 +0x30,把R0的内容加 0x30。 说明:以上两条指令中,第二个源操作数 #1 和#0x30为立即数。立即数必须以#作为前缀,对于16进制的立即数,要求有"0x"或者"&"符号。
2. 寄存器寻址 将寄存器中的值作为操作数,这种方式即为寄存器寻址。此种方式较为各类微处理器常用,执行效率高。 例: ADD R0,R1,R3 ;R0 <==R1+R3 将R1和R3的内容相加,结果存放到R0。
3. 寄存器移位寻址 其是将2 寄存器寻址做变化而得到的一种新的寻址方式。即移位,第二个操作数通过相应移位和第一个操作数运算后放到目的寄存器中。 例: ADD R0,R1,R3,LSL #3 ;R0 <== R0+R3*8 ,R3的值左移3位就是乘以8,结果与R1的值相加,存放到R0. ARM的移位(或者循环移位)操作有如下几种: LSL 逻辑左移,寄存器中低位空出的有效位用0填充 LSR 逻辑右移,寄存器中高端空出的有效位用0填充 ASR 算数右移,移位过程中必须保持符号位不变,即若源操作数为正,则高位用0填充,若为负,则高位用1填充。 其每移一位的操作和逻辑右移相同,仅是如果原最高位为1,则移位后最高位补1,所以在移大于1位时左边的高位都是1. 即: MOV R1,#0 MOV R2,#&80000000 ;此处立即数为负数, MOV R1,R2,ASR #3 R1 内的值为 0xF0000000 若立即数换为0x40000000,则R1的值最后为0x08000000.
ROR 循环右移,一处的最低位移到空出的最高位 RRX 扩展的循环右移,操作数右移一位(每次执行只能移动1位),高端空出的位用进位标志位C的当前值来填充。
4.寄存器间接寻址 寄存器间接寻址,就是以寄存器中的值作为操作数的地址。这种寻址方式类似于c语言中取指针对应的变量的值 *p。 例: ADD R0,R1,[R2] ;R0 《==R1 + [R2] LDR R0,[R1] ;R0 <==[R1] STR R0,[R1] ;[R1] <== R0 第一条指令为将R2的值作为操作数的地址,将此地址对应的位置的操作数和R1相加,存放到R0 ,[R2]类似于 取指针对应的值 *p。 第二条指令为将R1的值作为地址的寄存器中的数传送到R0中。类似于c语言 R0 = *R1; 第三条指令将R0的值传送到R1的值作为地址的寄存器中。 类似于c语言中 *R1 = R0;
5.基址变址寻址 这种寻址方式就是将寄存器(一般为基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到操作数的有效地址。 这种方式长用来访问基址附近的地址空间。 例: LDR R0,[R1,#4] ;R0 <==[R1 +4] LDR R0,[R1,#4]! ;R0<==[R1+4] 、 R1<==R1 +4 LDR R0,[R1],#4 ;R0<==[R1] 、R1 <==R1+4 LDR R0,[R1,R2] ;R0 <==[R1+R2] 以上是常见的4中变址寻址方式,通过前面4中寻址的学习,我们可以认为 符号"[]"意为里面的数是地址,用符号作用后是取地址对应的值。即 *(int *)强制类型转换, #即代表的立即数。那么第一条和第四条就很容易理解了。 第二三条指令可以看出,相当于两个动作,第一个动作是将取得的值存放到R0,第二个都是R1的地址自加4.
6.多寄存器寻址 多寄存器寻址方式可以实现一条指令完成多个寄存器值的传送。最多可以传送16个通用寄存器的值。 例: LDMIA R0,{R1,R2,R3,R4} ;R1 <==[R0] ;R2 <==[R0+4] ; R3 <==[R0+8] ;R4 <==[R0+12] 该条指令的后缀 IA 即 Increment After 的缩写,表示在每次执行完加载/存储操作之后,R0按字长度(即4字节)增加,因此,指令可以将连续多个存储单元的值传送到R1-R4中。
7.相对寻址 这种寻址方式从名称上就可以看出和基址变址寻址方式类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号为偏移量,将两者相加之后得到操作数的有效地址。 以下程序完成了子程序的调用和返回,跳转指令BL采用相对寻址方式:
[plain] [url=]view plain[/url][url=]copy[/url][url=]print[/url][url=]?[/url] [plain] [url=]view plain[/url][url=]copy[/url][url=]print[/url][url=]?[/url]
8.堆栈寻址
堆栈(STACK)是一种十分常用的数据结构,按照先进后出(First In Last Out,FILO)的方式工作。堆栈使用一个叫做堆栈指针的专用寄存器指示当前操作位置,堆栈指针总是指向栈顶。ARM中使用LDMFD和STMFD指令来支持POP出栈操作和PUSH进栈操作,R13被用作堆栈指针。
例: STMFD R13!,{R0~R4} ; LDMFD R13!,{R0~R4} ; 第一条指令将R0~R4中的数据压入堆栈 第二条指令将数据出栈,回复R0~R4的值。 ARM内存管理单元MMU是存储器管理单元的缩写,是用来管理虚拟内存系统的器件。MMU通常是CPU的一部分,本身有少量存储空间存放从虚拟地址到物理地址的匹配表,此表称作TLB(转换旁置缓冲区)。所有数据请求都送往MMU,由MMU决定数据是在RAM中还是在大容量存储器设备中。如果数据不在RAM中,MMU将产生缺页中断。 MMU的两个主要功能如下: 1.将虚地址转换成物理地址。 2.控制存储器存取允许。 嵌入式系统中,存储系统差别很大,可包含多种类型的存储器件,如FLASH、SRAM、SDRAM、ROM等,这些不同类型的存储器件速度和宽度等各不相同;在访问存储单元时,可能采取平板式的地址映射机制对其操作,或需要使用虚拟地址对其进行读写;系统中,需引入存储保护机制,增强系统的安全性。为适应如此复杂的存储体系要求,ARM处理器中引入了存储管理单元来管理存储系统。 在实践中,使用MMU解决了如下几个问题: 1.使用DRAM作为大容量存储器时,如果DRAM的物理地址不连续,这将给程序的编写调试造成极大不便,而适当配置MMU可将其转换成虚拟地址连续的空间。 2.ARM内核的中断向量表要求放在0地址,对于ROM在0地址的情况,无法调试中断服务程序,所以在调试阶段有必要将可读写的存储器空间映射到0地址。 3.系统的某些地址段是不允许被访问的,否则会产生不可预料的后果,为了避免这类错误,可以通过MMU匹配表的设置,将这些地址段设为用户不可存取类型。 启动程序时生成的匹配表中包含地址映射,存储页大小(1M、64K、4K)以及是否允许存取等信息。MMU通过虚拟地址和页面表位置信息,按照转换逻辑获得对应物理地址,输出到地址总线上。 MMU的作用有两个:地址翻译和地址保护。软件的职责是配置页表,硬件的职责是根据页表完成地址翻译和保护工作。如果CPU没有硬件MMU,那么这张表将毫无意义。必须从CPU的角度去理解内存映射这个概念,内存映射是CPU通过MMU把一条指令中要访问的地址转换为物理地址,然后发送到总线上的过程。 在实际的应用中,可能会把两片不连续的物理地址空间分配给SDRAM。而在操作系统中,习惯于把SDRAM的空间连续起来,方便内存管理,且应用程序申请大块的内存时,操作系统内核也可方便地分配。通过MMU可实现不连续的物理地址空间映射为连续的虚拟地址空间。 操作系统内核或者一些比较关键的代码,一般是不希望被用户应用程序所访问的。通过MMU可以控制地址空间的访问权限,从而保护这些代码不被破坏。 MMU的实现过程,实际上就是一个查表映射的过程。建立页表(translatetable)是实现MMU功能不可缺少的一步。页表位于系统的内存中,页表的每一项对应于一个虚拟地址到物理地址的映射。每一项的长度即是一个字的长度(在ARM中,一个字的长度被定义为4字节)。页表项除完成虚拟地址到物理地址的映射功能之外,还定义了访问权限和缓冲特性等。 MMU的映射分为两种,一级页表的变换和二级页表变换。两者的不同之处就是所实现的变换地址空间大小不同。一级页表变换支持1M大小的存储空间的映射,而二级可以支持64KB、4KB和1KB大小地址空间的映射。 要实现从虚拟地址到物理地址的映射,必然会遇到一个问题,如何找到这个页表。对于表的查找,要知道这个表的基地址和偏移地址,在具有MMU功能的处理器中,集成了一个被称为CP15的协处理器,该协处理器的C2寄存器中用于保存页表的基地址, ARM MMU执行以下一些功能,将虚拟地址转换成物理地址;控制存储访问权限;决定存储器中每一页的Cache和写缓冲器的行为。当禁用MMU时,所有的虚拟地址一一映射到与其相同的物理地址。如果MMU在转换一个地址时失败,就会产生一个中止异常。MMU只有在转换失败、权限错误和域(domain)错误时,才会中止。 MMU的主要配置和控制模块如下:页表、转换旁路缓冲器、域和访问权限、Cache和写缓冲器、CP15、快速上下文切换扩展。
|