计算机组成原理三体系结构与组成

计算机的指令集体系结构(ISA)从汇编语言程序员的角度描述了计算机,并强调了计算机的功能,而不是它的内部组成或实现。ISA说明了计算机能做什么,而计算机组成则说明了它是如何做的

存储程序计算机

(1) ARM这一类处理器采用了存储程序体系结构,他将程序和数据放在同一个存储空间内,采用了取指-执行模式执行,即按照顺序从内存读取指令、译码、执行。
(2) 寄存器是位于CPU内部的存储单元,类似于内存中的存储单元。寄存器使用名字而不是地址来访问,如r0,r1,…,r15(ARM的命名),或是AX,BX,CX,DX,SP,BP,SI(Intel命名),或是D0,D1,…,D7(Freesacle的命名)
(3) 计算机指令的操作码可以使用很少的几位来引用寄存器,指令中用来选择寄存器的字段一般为3~5位,具体数值取决于计算机中程序课件寄存器的个数。
(4) CPU中的寄存器有几个功能,一些寄存器是高速暂存寄存器,用于保存数据或数据单元的地址(即指针)。另外一些事特殊功能寄存器,如对一个循环的次数进行计数的循环计数器,有的用来记录处理器的状态。CPU中最重要的寄存器是程序计数器(PC),它记录了要执行的下一条指令的地址。
(5) 计算机指令有多种格式,通用计算机提供了以下3种指令格式:
LDR寄存器目的,存储单元源
STR寄存器源,存储单元目的
Operation寄存器目的,寄存器源1,寄存器源2
例:LDR r1,1234 :LDR指令吧数据从存储器复制到寄存器,将地址为1234的存储单 元中的数据读到寄存器r1中
MBR 存储器缓冲寄存器,保存了刚从存储器中读出的数据,或将要写入存储器的数据
MAR 内存地址寄存器,保存了读或写操作正在访问的存储单元地址
CU 控制单元
ALU 算术逻辑运算单元
PC :程序计数器,保存了要执行的下一条指令的地址
IR:指令寄存器,存放最近从存储器中读出的指令,也就是当前正在执行的指令
ro-r7:寄存器文件,包括8个通用目的寄存器r0,r1,…,r7,用于存放临时数据

寄存器的可见性

(1) 寄存器有三种类型
1,通用寄存器,用来保存计算过程产生的临时数据。ARM有16个通用寄存器,r0,r1,r2……,r15。寄存器r14和r15是通用寄存器,程序员可以访问这两个寄存器,然而,r14与r15又在ARM体系结构中扮演着特殊角色
2,特殊功能寄存器,用于特定功能。如,PC指向要执行的下一条执行指令。其他特殊功能寄存器还有状态寄存器、栈指针寄存器以及CPU标识寄存器等。
3,不可见寄存器,不属于处理器体系结构的一部分,不能被程序员直接使用。如,指令寄存器IR和内存地址寄存器MAR等,这些都是实现计算机所必需的,但又不属于ISA的一部分。

为什么程序计数器每次取指令要加4

计算机存储器按照字节编址,各个字节存储单元依次命名为0,1,2…。但是32位微处理器使用32位指令和32位字数据。
因此每一次取指令后PC必须加4,因为4字节*8位/字节 = 32位 = 1指令字

扩展处理器:常量处理

LDR r1,1234,这里的“1234”是指地址为1234的存储单元的内容。假设要将数值1234载入寄存器r1中,这样的数字叫作立即操作数。立即数是一个在运算中可以直接使用的数,与存储单元的值完全不同,需要用哈希符号(#)前缀来声明。

扩展处理器:流控制

(1) 流控制是指任意能够改变程序中指令顺序执行的动作,它是指计算机非顺序执行指令的能力
(2) 流控制是指转移到程序中特定位置的分支和跳转指令、子程序/过程调用,返回、中断以及操作系统调用。
(3) 流控制的典型例子就是条件行为,它允许处理器在两个可能的动作序列中选择一个执行

条件码寄存器(CCR)

ALU的信息将被写入条件码寄存器(CCR),它保存了各种用于测试的条件(如,零、负、正)。当ALU执行一个操作时,它会更新CCR中的零位、借位位、负位以及溢出位。
从使用PC中的地址到存储器地址中取出条件分支指令开始。分支指令读出CCR的内容,其内容由上一条指令的结果决定。在执行时,条件分支指令将完成以下两个动作中的一个:
(1)如果CCR中的测试位为false,则处理器从[PC]+4处取出下一条指令、
(2)如果CCR中的测试位为true,则PC从IR的操作数字段载入新的地址,并跳转到新地址处执行

状态信息

计算机执行一个操作时,将状态或条件信息保存在CCR中,处理器记录下结果是否为0(Z),结果的二进制形式是否为负(N),是否产生进位位(C),是否算术溢出(V)。
有些处理器需要程序员强制更新CCR

寄存器

片内的一个指针寄存器保存了存储器中寄存器的地址。
寄存器对于提高计算机性能和实际指令集设计是很有必要的。
设计一条ADD P = Q+R的计算机指令,P,Q,R都是存储地址。

假设操作码为16位(ADD部分),地址空间为32位,则指令长度为16+32+32+32 = 112位,典型的真实计算机的指令长度为16位或32位,所以112位的指令长度是不可行的。

实际计算机用寄存器实现片上存储,寄存器的功能与存储单元一样,唯一的区别在于访问的便捷性和响应时间。仅需很少的指令就可以指定一个片上寄存器
如:某计算机的操作码为8位,带有8个片上寄存器(用3位就可以访问r0-r7中的一个),就能用8+3+3+3=17位实现指令ADD P = Q+R。

寻址方式概述

指令对数据进行操作,并且必须将数据移动到其被处理的地方。指定数据的方式统称为“寻址方式”。3种基本寻址方法为:
(1) 立即数寻址
最简单的寻址方式,其操作数是指令的一部分。
如操作P= Q+5,这里的5就是立即数,它没有被保存在存储单元或寄存器中,而是指令的组成部分。
ARM处理器使用前缀#指定立即操作数,如ADD r1,r2,#4完成了操作[r1]<-[r2]+5
(2) 直接寻址
也称为绝对寻址。把操作数地址用作指令的一部分。
如指令ADD P,Q,R表示将存储单元Q的内容与存储单元R的内容相加,并将结果保存在存储单元P中
直接寻址在CISC计算机上得到广泛使用,如Intel IA32或68K系列,LOAD/STORE 型计算机,如ARM,没有实现直接寻址
(3) 间接寻址
更严格地说,叫作寄存器间接寻址。在寄存器间接寻址中,指令给出了包含操作数地址的寄存器的地址。
获取一个操作数需要3次访问:读指令,读含有操作数地址的寄存器,以及最后读出实际的操作数。
含有操作数地址的寄存器称为指针寄存器。load/store型计算机(如ARM),使用这种寻址方式访问存储器操作数

寄存器间接寻址有许多变种,最常用的格式是带偏移量的寄存器间接寻址,其中操作数的地址由寄存器内容加上常量或偏移量指定。
典型格式为:
LDR r2,[r3,#8]; 把寄存器r3+8所指存储单元的内容复制到寄存器r2中

存储器与寄存器寻址

寄存器与存储单元之间没有本质区别,其区别主要体现在它们的相对访问速度以及指定一个寄存器和一个存储单元所需的地址位数上。

由此推出,(ARM)这些计算机不支持存储器-存储器型寻址方式
就是操作数占用位数太多,一个指令的位数最多为16/32/64位。

操作码与指令

计算机体系结构设计中最重要的一个因素是每条指令中操作数地址的数量。
如:实现了指令ADD r1,r2,r3的指令集是三地址计算机,而实现了ADD r1,r2指令的计算机是双地址计算机。在此主要介绍三地址、双地址、单地址、零地址的计算机。

零地址计算机

零地址计算机使用根本没有地址的指令。零地址计算机对位于栈顶的数据进行处理,因此通常也被称作栈计算机。需要通过load和store指令从存储器读出数据或把数据保存到存储器中。

单操作数运算(一元运算,如取负、清零、递增、递减)作用于栈顶数据,而双操作数运算(二元运算,如加、乘、逻辑或)首先从栈顶取出两个元素,进行运算,然后将结果入栈。

将一个数据放入栈顶的操作叫做入栈(PUSH),将栈顶取出一个数据的操作叫作出栈(POP)

一个半地址计算机

Intel IA32系列与Freescale系列通常叫作一个半地址计算机。

因为它们的指令指定了两个操作数,一个操作数是存储器地址,另一个操作数是寄存器地址。寄存器地址被讽刺地称为半个地址–与GB量级的存储空间相比,寄存器数量很少。

ARM指令集体系结构

ARM是一个32位的计算机,采用寄存器-寄存器的体系结构,使用load/strore指令在存储器和寄存器之间移动数据。所有操作数都是32位,除了几条乘法指令会产生64位结果并保存在两个32位寄存器中

ARM寄存器集

ARM的16个程序员课件寄存器(r1r15)以及它的状态寄存器。ARM共有14个通用寄存器r0r13.寄存器r13被保留用作栈指针,r14存放子程序返回地址,r15为程序计数器。

由于r15能够被程序员访问,因此能够执行可以计算的分支(如高级语言case语句所用的操作类型)。ARM的16个寄存器需要4位地址,相对于32个寄存器(5位地址)的RISC处理器来说,每条指令可以节约3位。这种方法使得ARM的指令比一些RISC处理器丰富得多。

寄存器r13被保留用作栈指针。与特殊功能寄存器r14和r15不同,它们的附加功能由ARM硬件实现,仅当程序员需要r13作为栈指针时它才会成为栈指针。

ARM指令集

指令集分类方法:数据移动、算术运算、逻辑运算、移位、程序控制

更新ARM条件码

与绝大多数CISC体系结构不同,ARM不会在算术和逻辑运算后自动更新状态标志。ARM提供按需更新模式,尽在当前指令助记符带有后缀S时才会自动更新条件码。
如ADD→ADDS

ARM汇编语言

所有处理器的汇编语言都源于芯片设计者的精雕细琢。ARM指令的格式如下:
Label Op-code operand1,operand2,operand3;comment

汇编程序有两部分组成:计算机可执行指令和告诉汇编器运行环境有关信息的汇编伪指令。汇编伪指令告诉汇编器代码在存储器中的位置,为变量分配存储空间,以及设置程序运行时所需的初始数据。

ARM程序结构:

反汇编就是将汇编器产生的代码转换回汇编语言源程序
一些汇编语言程序所用的约定:
(1) 前缀#可将立即数用作操作数
(2) #后面的数字一般视为十进制的,带前缀0x表示十六进制,如MOV r0,#0x2C
(3) ASCII字符采用单引号表示,如:CMP r0,#‘A’;比较是字母’A’吗?

伪指令

伪指令是程序员可用的指令,但不是处理器ISAde一部分,伪指令是一种速记形式,程序员可用它简单的表示一个动作,并使汇编器生成合适的代码。

算术指令

加法:ADD
减法:SUB
取负:NEG
比较:CMP
乘法:MUL
移位:LSL,LSR,ASL,ASR,ROL,ROR
(1) 减法与减法
绝大多数微处理器都实现了带进位的加法指令,能够将两个操作数和条件码寄存器中的进位位加到一起。这条指令会使字长大于计算机固有字长的链接运算更加方便
(2)比较
通过执行指令CMP Q,P比较P和Q时,将发生显示比较,这条指令会计算Q-P但不会保存结果。比较操作会修改CCR的内容,后面的指令会测试CCR的值以决定按顺序继续执行还是跳转

位操作

逻辑操作也叫位操作,这些操作被应用到寄存器的每一位。微处理器一般只支持AND、OR、NOT、EOR(异或)操作。

逻辑运算的典型应用就是数据合并,即把多个变量合并到一个寄存器或存储单元中。

移位操作:

移位操作就是把字中的位向左或向右移动一个或多个位置。当移位一个位串时,串的一段的位会被丢弃,并在另外一端补充新的位
(1) LSL逻辑左移,LSR逻辑右移:零移进来,移出去的位被复制到条件码寄存器的进位位
(2) ASL算术左移,ASR算术右移:操作数要么乘以2(ASL),要么除以2(ASR)。以2的补码表示的操作数的符号位保留。移出去的位被复制到进位位,算术左移与逻辑左移是等价的。算术右移会保留符号位,每次右移后符号位会自动复制。
(3) ROL循环左移,ROR循环右移:移出的位被复制到另外一端空出位(也就是,没有位在循环过程中丢失)。移出去的位也被复制到进位位

ARM有4条测试与比较指令CMP、CMN、TST、TEQ,这些指令会显示更新条件码标志,因此无需再指令后添加s

相等测试指令TEQ

确定两个操作数是否相等,如果相等将Z位置1,否则将Z位清0
TEQ与CMP指令类似,测试时TEQ不影响溢出标志的状态而仅修改Z位。相反地,CMP会更新溢出标志

条件执行

汇编语言程序员在指令助记符后添加合适的条件以指明条件执行模式
如:ADDEQ r1,r2,r3
指定仅当条件码中的Z位因为前一个结果为0而被置为1时,加法操作才会被执行。

ARM的立即数实现方法

ARM在指令中提供了12位的立即数字段,但不支持值在0~4095之间无符号立即数或值在-2048~2047之间的12位有符号立即数。实际上ARM提供的是可按2的幂缩放的8位立即数。

当操作码的第25位为0时,ARM将进行一次移位操作,当25位为1时,操作数2字段将编码12位立即数,它被分成两部分:8位立即数和4位对齐码。

寄存器间接寻址

操作数的地址保存在寄存器中,这种寻址方式叫作寄存器间接寻址,也叫索引寻址或基址寻址。ARM的立即数偏移量为12位。它确实是12位立即数,不是8位可缩放的值

什么时候12真的是12

ARM处理器指定12位常量作为立即操作数。常量位为8位数并通过4位对齐码进行放大。

然而,当ARM处理器指定某个立即数偏移量作为索引地址的一部分时,它就是真正的12位数

寄存器间接寻址通过3个读操作来访问一个操作数:
(1) 读指令得到指针寄存器
(2) 读指针寄存器得到操作数地址
(3) 读操作数地址所指的存储单元得到操作数
寄存器间接寻址可以在运行时修改寄存器的内容,而寄存器中含有指向实际操作数的指针,因此地址是变量,允许访问如数组、列表、矩阵、向量、表格等数据结构

带偏移量的寄存器间接寻址

操作数有效地址是寄存器的内容加上编码在load/store指令的立即数偏移量,这种寻址方式也叫基址加位移寻址。

ARM的自动前索引寻址方式

通过将偏移量加到基址寄存器上ARM实现了两种自动索引方式。这两种方式的差别在于基址寄存器递增的时机–要么访问寄存器之前,要么在之后。

ARM的自动前索引寻址方式是在有效地址后面添加后缀!来表示。如:
LDR ro,[r1,#8]! ;将寄存器r1+8所指存储单元的字加载到r0中
然后将r1加8以更新指针

ARM的自动后索引寻址方式

自动后索引寻址方式首先访问基址寄存器所指的存储单元中的操作数,然后将基址寄存器递增。如: LDR r0,[r1],#8;将r1所指的字加载到r0,然后完成后索引,即r1加8后索引把偏移量放在方括号的外面(如[r1],#8),RTL定义NBF为:
[r0]<-[[r1]] 访问基址寄存器r1所指存储单元
[r1]<-[r1]+8 加上偏移量更新指针(基址寄存器)

巴科斯范式(NBF)

ARM的load/store指令的形式语法(巴克斯范式,NBF)定义为:
LDR|STR {cond}{B} Rd,[Rn,offset]{!}
or
LDR | STR {cond}{B} Rd,[Rn],offset
大括号{}表示字段是可选的
|表示二中选一
可选{B}指明字节操作数

子程序调用与返回

子程序(也叫过程、函数、方法)是一个能被调用和执行并返回到调用点那条指令的代码段
两个问题:如何将参数传递给子程序或从子程序中传递出来?怎么从子程序返回到调用点?

指令BSR Proc_A 调用子程序Proc_A。
处理器将调用代码中要执行的下一条指令的地址保存到一个安全的地方,然后把目标地址Proc_A,子程序的第一条指令,加载到程序计数器中。

把一个非顺序地址加载到PC就强制跳转到子程序中。
在子程序末尾,从子程序中返回指令RTS,使处理器返回到子程序调用点的下一条指令。

ARM对子程序的支持

ARM没有像CISC处理器那样提供全自动的子程序调用与返回机制。

ARM的分支并链接指令BL,自动将返回地址保存在寄存器r14中。

分支指令的格式中带有一个8位操作码和24位有符号的相对程序计数器的偏移量。由于分支目标地址是一个字地址,分支地址按32位字边界对齐,因此将24位偏移量左移两位,把字偏移地址转换成字节地址,然后26位字节地址被符号扩展成32位,并被加到PC上,由于分支地址偏移量为26位(24+2),因此条件分支的寻址范围为PC-32M~PC+32M字节

子程序与栈

微处理器中的栈由栈指针指向存储器中的栈顶来实现,当数据项入栈时,栈指针向上移动,当数据项出栈时,栈指针向下移动。

实现栈时需要作出两个决定:一是当数据项进栈时是向低位地址方向向上生长还是向高位地址方向向下生长,另一个决定是栈指针指向当前位置栈顶的数据项还是指向栈顶上的第一个空白位置。

数据组织与端格式

一般认为数据在存储器中的存储方式是一个无关紧要的问题。如,十进制计算机按照1、9、8、4或4、8、9、1的顺序保存数据1984.然而,位和字节的编号方法会引起使用不同方法存储数据的处理器之间的不兼容

字节中的位:绝对大多数微处理器(ARM,Intel,Freescale)都是采用从低位到高位,有些微处理器,如PowerPC,则与之相反
字中的字节:要么最高字节放在字的最高位字节地址处,要么将最高字节放在字的最低位字节地址处。如果将最高字节放在最低地址,这种顺序叫作大端格式,如果将最高字节放在最高地址,这种顺序叫作小端格式。Intel微处理器使用小端格式,而Freescale微处理器使用大端格式。

数据组织和ARM

ARM存储器是按字节编址的,连续的两个32位字,地址相差4个字节。字数据必须按照4字节字边界对齐存放。

任何时候ARM从存储器中取出一条指令,地址的最低两位总是0,即指令地址的格式为xxxxx,…,xxx00,它能确保地址是边界对齐的。16位数(半字)按照半字边界地址对齐。

溢出判断

例如两个8位2进制相加所得的结果放入16位中,在向右移7位,首先先判断是否为零,为零表示没有溢出,不为零则与-1做比较,如果等于-1则没有溢出,反之溢出

块移动指令

用一条指令在寄存器组合存储之间传送数据。

猜你喜欢

转载自blog.csdn.net/weixin_44806700/article/details/120317171