静态随机存储器

静态随机存储器实验 实验目的 (1) 掌握静态随机存储器 RAM 工作特性及数据的读写方法。 (2) 基于信号时序图,了解读写静态随机存储器的原理。 实验设备 PC 机一台,TDX-CMX 实验系统一套。 实验原理 实验所用的静态存储器由一片 6116(2K×8bit)构成(位于 MEM 单元),如图 2-1-1 所示。 6116 有三个控制线:CS(片选线)、OE(读线)、WE(写线),其功能如表 2-1-1 所示,当片选有效(CS=0)时,OE=0 时进行读操作,WE=0 时进行写操作,本实验将 CS 常接地。 实验原理图如图 2-1-2 所示,存储器数据线接至 CPU 内总线,内总线上接有 8 个 LED 灯显示 D7…D0 的内容。地址线接至地址总线,地址总线上接有 8 个 LED 灯显示 A7…A0 的内容,地址由地址锁存器(74LS273,内嵌于 ABI 单元)给出。数据开关(位于 CON 单元的 SD17..SD10)经一个三态门(74LS245)连至 CPU 内总线,分时给出地址和数据。地址寄存器为 8 位,接入存储器的地址 A7…A0,高三位地址 A10…A8 接地,所以其实际容量为 256 字节。 实验箱中所有单元的时序都连接至时序与操作台单元,CLR 都连接至 CON 单元的 CLR 按钮。实验时 T3 由时序单元给出,其余信号由 CON 单元的对应二进制开关模拟给出,其中 RD、 WR 低有效,SW_B 低有效,LDAR 高有效。 ...

November 5, 2025 · 2 min · farmer3-c

线段树

线段树是一种特殊的数据结构,它可以在 $O(\log n)$ 的时间复杂度内实现单点修改、区间修改、区间查询(区间求和,求区间最大值,求区间最小值)等操作。 最简单的线段树的构建: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream> #include <vector> using namespace std; // 定义线段树的节点 struct Node { int l, r; // 左右子节点的下标 int sum; // 区间和 }; vector<Node> tree; // 存储线段树的数组 // 构建线段树 void build(int l, int r, int index, vector<int>& nums) { tree[index].l = l; tree[index].r = r; if (l == r) { // 叶子节点 tree[index].sum = nums[l]; return; } int mid = (l + r) / 2; build(l, mid, index * 2, nums); // 构建左子树 build(mid + 1, r, index * 2 + 1, nums); // 构建右子树 tree[index].sum = tree[index * 2].sum + tree[index * 2 + 1].sum; // 计算区间和 } // 区间查询 int query(int l, int r, int index) { if (tree[index].l >= l && tree[index].r <= r) { // 当前区间完全包含在查询区间内 return tree[index].sum; } int mid = (tree[index].l + tree[index].r) / 2; int sum = 0; if (l <= mid) { // 查询区间和左子树有交集 sum += query(l, r, index * 2); } if (r > mid) { // 查询区间和右子树有交集 sum += query(l, r, index * 2 + 1); } return sum; } // 单点修改 void update(int pos, int val, int index) { if (tree[index].l == tree[index].r) { // 叶子节点 tree[index].sum = val; return; } int mid = (tree[index].l + tree[index].r) / 2; if (pos <= mid) { // 修改的位置在左子树 update(pos, val, index * 2); } else { // 修改的位置在右子树 update(pos, val, index * 2 + 1); } tree[index].sum = tree[index * 2].sum + tree[index * 2 + 1].sum; // 更新区间和 } int main() { vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 原始数组 int n = nums.size(); // 数组长度 tree.resize(n * 4); // 线段树的大小为 4n build(0, n - 1, 1, nums); // 构建线段树 cout << query(0, 4, 1) << endl; // 查询区间 [0, 4] 的和 update(2, 10, 1); // 将第 2 个元素修改为 10 cout << query(0, 4, 1) << endl; // 查询区间 [0, 4] 的和 return 0; } 构建解释: 递归地将数组分为左右两个子数组,直到子数组长度为 1,此时该子数组的区间和就是该子数组的元素值。 ...

October 20, 2025 · 3 min · farmer3-c

什么是无线网卡

什么是无线网卡? 无线网卡,又称无线网络卡或 Wi-Fi 卡,是一种硬件组件,它使计算机或智能手机等设备能够连接到无线网络。它允许设备通过无线电频率信号与其他设备或接入点进行通信和数据交换,无需物理电缆。 无线网卡的优点是什么? 无线网卡最显著的优势在于其自由移动性。用户无需通过线缆被限制在特定位置,即可连接网络和访问互联网。 无线网络可以同时容纳多台设备,因此具有高度的可扩展性。这在许多设备需要连接到同一网络的环境中尤为重要,例如拥挤的公共场所或企业环境。 无线网卡在连接和实现物联网设备之间的通信方面起着关键作用。它们促进传感器、设备和中央服务器之间的数据交换,推动物联网生态系统的增长 无线网卡是如何工作的? 无线网卡通过使用射频信号来传输和接收数据。它们连接到网络的接入点,为数据流创建一条虚拟路径。这些网卡采用先进的加密技术来确保数据安全,使无线通信既高效又安全。 What is a Wireless Card? And How Does it Work? Wireless security

October 16, 2025 · 1 min · farmer3-c

Introduction to Linear Programing

What is Linear Programming? Linear programming (LP), also known as linear optimization, is a powerful mathematical method used to find the best possible outcome in a given situation. It’s used to achieve results like maximum profit or minimum cost, where the objective and the constraints are expressed as linear relationships. In essence, LP provides a systematic way to solve optimization problems. Standard Form To solve a linear programming problem, we first need to express it in standard form. This is the most common and intuitive way to structure an LP problem and consists of three key components: ...

September 14, 2025 · 5 min · farmer3-c

machine learning

机器学习 definition 机器学习(ML)是人工智能的一个研究领域,关注于开发和研究能够从已有数据中学习并推广到未见数据,从而无需明确指令就能执行任务的统计算法。在机器学习的一个子学科中,深度学习领域的进展使得神经网络——一种统计算法——在性能上超越了许多之前的机器学习方法。 统计学和数学优化(数学规划)方法是机器学习的基础。数据挖掘是一个相关的研究领域,专注于通过无监督学习进行探索性数据分析(EDA)。 从理论角度来看,大概近似正确学习为描述机器学习提供了一个框架。 history 机器学习一词由 IBM 员工、计算机游戏和人工智能领域的先驱亚瑟·塞缪尔于 1959 年提出。在这个时期,也使用了同义词“自教学计算机”。 最早的机器学习程序出现在 20 世纪 50 年代,当时亚瑟·萨缪尔发明了一个计算机程序,用于计算跳棋双方获胜的概率,但机器学习的历史可以追溯到人类数十年来研究认知过程的愿望和努力。1949 年,加拿大心理学家唐纳德·赫布出版了《行为的组织》一书,书中介绍了一种由神经细胞之间特定相互作用形成的理论神经结构。赫布的神经元相互作用模型为人工智能和机器学习算法在节点(计算机用于通信的人工神经元)下如何工作奠定了基础。其他研究人类认知系统的研究者也促进了现代机器学习技术的发展,包括逻辑学家沃尔特·皮茨和沃伦·麦克洛克,他们提出了早期的神经网络数学模型,以形成模拟人类思维过程的算法。 Modern day Machine Learning algorithms are broken into 3 algorithms types: Supervised Learning Algorithms, Unsupervised Learning Algorithms, and Reinforcement Learning Algorithms. Current Supervised Learning Algorithms have objectives of classification and regression. Current Unsupervised Learning Algorithms have objectives of clustering, dimensionality reduction, and association rule. Current Reinforcement Learning Algorithms focus on decisions that must be made with respect to some previous, unkown time and are broken down to either be studies of model based methods, and model free methods. theory 学习者的一个核心目标是泛化其经验。在此文中,泛化是指学习机器在经历学习数据集后,能够对新未见过的示例/任务进行准确执行的能力。训练示例来自某个通常未知的概率分布(被认为是发生空间的代表),而学习者必须构建一个关于这个空间的通用模型,使其能够在新情况下产生足够准确的预测。 ...

September 14, 2025 · 2 min · farmer3-c

datalab

CS:APP Data Lab The purpose of this lab is to become more familiar with bit-level representations of integers andfloating point numbers. You’ll do this by solving a series of programming “puzzles.” Many of these puzzles are quite artificial, but you’ll find yourself thinking much more about bits in working your way through them.———— Harry Bovik bitXor bitXor - x^y using only ~ and & Example: bitXor(4, 5) = 1 Legal ops: ~ & Max ops: 14 Rating: 1 1 2 3 4 5 int bitXor(int x, int y) { // x^y=(x&~y)|(~x&y)=~(~x&~y)&~(x&y) return ~(~(x & ~y) & ~(~x & y)); } tmin tmin - return minimum two’s complement integer Legal ops: ! ~ & ^ | + « » Max ops: 4 Rating: 1 1 2 3 4 int tmin(void) { return 1 << 31; } isTmax isTmax - returns 1 if x is the maximum, two’s complement number, and 0 otherwise Legal ops: ! ~ & ^ | + Max ops: 10 Rating: 1 1 2 3 4 int isTmax(int x) { return !(~(x + 1) ^ x) & !!(x + 1); } allOddBits allOddBits - return 1 if all odd-numbered bits in word set to 1 where bits are numbered from 0 (least significant) to 31 (most significant) Examples: allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1 Legal ops: ! ~ & ^ | + « » Max ops: 12 Rating: 2 1 2 3 4 5 6 int allOddBits(int x) { int m = (0xAA << 8) | 0xAA; m = (m << 16) | m; return !((x & m) ^ m); } negate negate - return -x Example: negate(1) = -1. Legal ops: ! ~ & ^ | + « » Max ops: 5 Rating: 2 1 2 3 4 int negate(int x) { return ~x + 1; } isAsciiDigit isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters ‘0’ to ‘9’) Example: isAsciiDigit(0x35) = 1. isAsciiDigit(0x3a) = 0. isAsciiDigit(0x05) = 0. Legal ops: ! ~ & ^ | + « » Max ops: 15 Rating: 3 1 2 3 4 5 6 int isAsciiDigit(int x) { int a = x + (~0x30 + 1); int b = 0x39 + (~x + 1); return !((a >> 31) | (b >> 31)); } conditional conditional - same as x ? y : z Example: conditional(2,4,5) = 4 Legal ops: ! ~ & ^ | + « » Max ops: 16 Rating: 3 1 2 3 4 int conditional(int x, int y, int z) { return ((~(!!x) + 1) & y) | ((~(~(!!x) + 1)) & z); } isLessOrEqual isLessOrEqual - if x <= y then return 1, else return 0 Example: isLessOrEqual(4,5) = 1. Legal ops: ! ~ & ^ | + « » Max ops: 24 Rating: 3 1 2 3 4 5 6 7 8 int isLessOrEqual(int x, int y) { int a = (x >> 31) & 1, b = (y >> 31) & 1; int f = a ^ b; int d = y + ~x + 1; int ds = (d >> 31) & 1; return (f & a) | (!f & !ds); } logicalNeg logicalNeg - implement the ! operator, using all of the legal operators except ! Examples: logicalNeg(3) = 0, logicalNeg(0) = 1, logicalNeg(-5) = 0 Legal ops: ~ & ^ | + « » Max ops: 12 Rating: 4 1 2 3 4 int logicalNeg(int x) { return (((~x + 1) | x) >> 31) + 1; } howManyBits howManyBits - return the minimum number of bits required to represent x in two’s complement Examples: howManyBits(12) = 5 howManyBits(298) = 10 howManyBits(-5) = 4 howManyBits(0) = 1 howManyBits(-1) = 1 howManyBits(0x80000000) = 32 Legal ops: ! ~ & ^ | + « » Max ops: 90 Rating: 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int howManyBits(int x) { int sign = x >> 31, bit16, bit8, bit4, bit2, bit1; x = (sign & ~x) | (~sign & x); bit16 = (!!(x >> 16)) << 4; x >>= bit16; bit8 = (!!(x >> 8)) << 3; x >>= bit8; bit4 = (!!(x >> 4)) << 2; x >>= bit4; bit2 = (!!(x >> 2)) << 1; x >>= bit2; bit1 = (!!(x >> 1)); x >>= bit1; return bit16 + bit2 + bit4 + bit8 + bit1 + x + 1; } floatScale2 floatScale2 - Return bit-level equivalent of expression 2*f for floating point argument f. Both the argument and result are passed as unsigned int’s, but they are to be interpreted as the bit-level representation of single-precision floating point values. When argument is NaN, return argument Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while Max ops: 30 Rating: 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 unsigned floatScale2(unsigned uf) { unsigned sign = (uf >> 31) & 1, exp = (uf >> 23) & 0xff, frac = uf & 0x7fffff; if (exp == 0xff) return uf; if (exp == 0) { if (frac & 0x800000) { exp = 1; } frac <<= 1; return (exp << 23) | (sign << 31) | frac; } exp++; if (exp == 0xff) { return (sign << 31) | (0xff << 23); } return (sign << 31) | (exp << 23) | frac; } floatFloat2Int floatFloat2Int - Return bit-level equivalent of expression (int) f for floating point argument f. Argument is passed as unsigned int, but it is to be interpreted as the bit-level representation of a single-precision floating point value. Anything out of range (including NaN and infinity) should return 0x80000000u. Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while Max ops: 30 Rating: 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int floatFloat2Int(unsigned uf) { int sign = uf >> 31, exp = ((uf >> 23) & 0xff) - 127, frac = (uf & 0x7fffff) | 0x800000; if (exp >= 31) return 0x80000000u; if (exp < 0) return 0; if (exp < 23) { frac >>= (23 - exp); } else { frac <<= (exp - 23); } if (sign) { frac = -frac; } return frac; } floatPower2 floatPower2 - Return bit-level equivalent of the expression 2.0^x (2.0 raised to the power x) for any 32-bit integer x. The unsigned value that is returned should have the identical bit representation as the single-precision floating-point number 2.0^x. If the result is too small to be represented as a denorm, return 0. If too large, return +INF. Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while Max ops: 30 Rating: 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 unsigned floatPower2(int x) { if (x < -148) { return 0; } if (x < -126) { unsigned f = x + 148; unsigned fra = 1 << f; return fra; } if (x <= 127) { int k = x + 127; return k << 23; } return 0x7f800000; }

September 12, 2025 · 6 min · farmer3-c

Optimization for Unconstrained Differentiable Functions

Optimization for Unconstrained Differentiable Functions 1.1 Mathematical optimization $\frac{x ^2}{a^2} + \frac{y ^2}{b^2} = 1$ $\textit{f}_0 =4|x||y|$ A mathematical optimization problem, or just optimization problem, has the form maximize $\textit{f}_0 $ use x to represent $\textit{f}_0 $ $\textit{f}_0 =4xb\sqrt{1-\frac{x^2}{a^2}} $ $x>0$ we need to make $\textit{f'}_0 =4b \left( \sqrt{1 - \frac{x^2}{a^2}} - \frac{x^2}{a^2 \sqrt{1 - \frac{x^2}{a^2}}} \right)=0$ $ x=\frac{\sqrt2a}{2}$ find out the max of $\textit{f}_0$ is $2ab$ 1.2 Gradient descent Let’s try to find the minimum value of $\textit{f}(x,y) = x^3-y^3+3x^2-3y^2-9x$ ...

September 3, 2025 · 2 min · farmer3-c

总线系统

总线的概念和结构形态 总线的基本概念 总线是一组公共的传输线,用于连接计算机的各个部件(CPU、内存、I/O设备),实现信息共享和交换。总线由数据总线(传输数据)、地址总线(传输地址)和控制总线(传输控制信号)三部分组成。总线按时序可分为同步总线(有时钟信号)和异步总线(握手信号)。 总线的连接方式 常见连接方式: 单总线结构:所有部件都连接到同一总线,简单但可能成为瓶颈(如早期IBM PC)。 双总线结构:CPU与主存之间有一条高速内存总线,其他设备通过I/O总线与CPU通信(如南北桥架构)。 多总线结构:现代计算机使用多层次总线(如PCIe、DMI、QPI等)。 总线的内部结构 总线内部包括: 数据线:宽度决定一次传输的位数(如32位、64位)。 地址线:宽度决定可寻址空间。 控制线:包括读写信号、中断请求、总线请求/允许、时钟等。 此外还有电源线和地线。 总线结构实例 经典PC总线结构:CPU通过前端总线(FSB)连接北桥(内存控制器、AGP/PCIe),北桥连接南桥(PCI、ISA、USB、IDE等)。现代CPU集成内存控制器和PCIe控制器,芯片组简化为单芯片(PCH)。 总线接口 信息传送方式 信息传送方式包括:并行(多位同时传输)和串行(逐位传输)。串行总线(如USB、PCIe)使用差分信号,距离长、速率高、引脚少。 总线接口的基本概念 总线接口(或称适配器、控制器)是连接设备与总线的逻辑电路。它负责数据缓冲、协议转换、电平转换、中断处理等。接口必须满足总线规定的电气和时序规范。 总线仲裁 当多个设备请求使用总线时,仲裁器决定哪个设备获得总线控制权。 集中式仲裁 一个中央总线仲裁器(常位于CPU或北桥)负责判决。常见方式: 链式查询:通过一条总线请求线,优先级由物理位置决定(离仲裁器越近优先级越高)。简单但速度慢,且优先级固定。 计数器定时查询:仲裁器发计数值,设备匹配地址则获得总线。优先级可改变。 独立请求方式:每个设备有独立的请求线和允许线,仲裁器并行处理。速度快,但连线多(如PCI)。 分布式仲裁 没有中央仲裁器,每个设备都有仲裁逻辑,通过共享的仲裁总线竞争。例如,SCSI总线使用分布式仲裁。优点是无单点故障。 总线的定时和数据传送模式 总线的定时 定时决定什么时候发送地址和数据: 同步定时:使用统一时钟,所有操作在时钟边沿发生。简单但所有设备需以相同频率工作。 异步定时:基于握手信号(请求、应答)。允许不同速度的设备共存,但控制稍复杂。 总线数据传送模式 常见传送模式: 读/写周期:主设备发送地址和控制信号,从设备返回数据或接收数据。 突发传送:一次地址后连续传送多个数据(如SDRAM突发模式),提高吞吐量。 块传送:类似于突发。 分裂传送:主设备请求后释放总线,从设备准备好后再重新申请,提高了总线利用率。 PCI总线和PCIe总线 多总线结构 PCI(外设组件互连)是一种并行总线,工作频率33/66MHz,32/64位宽度,带宽最高约533MB/s。PCIe(PCI Express)是高速串行总线,采用点对点连接和交换结构,替代了PCI和AGP。 PCI总线信号 PCI总线信号包括:地址/数据复用线(AD[31:0])、控制信号(FRAME#, IRDY#, TRDY#)、仲裁信号(REQ#, GNT#)、错误报告(PERR#, SERR#)、中断信号等。 PCI总线周期类型 总线周期包括:配置周期(读写配置空间)、I/O周期、内存周期、特殊周期等。配置周期用于系统初始化时枚举设备。 PCI总线周期操作 一次PCI传输包含地址阶段(FRAME#有效,AD线上放地址)和数据阶段(IRDY#和TRDY#握手续传数据)。突发传输时地址只发一次,后续数据连续传送。 PCI总线仲裁 PCI总线使用集中式仲裁,每个主设备有独立的REQ#和GNT#线,仲裁器位于北桥或南桥。仲裁算法可以是轮询、优先级等。 PCIe总线 PCIe(PCI Express)采用高速串行差分信号(LANE),每个LANE发送速率从2.5GT/s(Gen1)到32GT/s(Gen5)及以上。支持x1、x2、x4、x8、x16、x32链路宽度。采用点对点交换结构,每个设备独享带宽。事务层使用数据包(TLP,事务层包)传递请求和完成。支持热插拔、电源管理、虚拟化等先进特性。PCIe已成为现代计算机的主流扩展总线,用于显卡、SSD、网卡等。

September 3, 2025 · 1 min · farmer3-c

中央处理器

CPU的功能和组成 CPU的功能 CPU是计算机的核心部件,其基本功能包括: 指令控制:从存储器取出指令,译码并执行。 操作控制:产生微操作信号,驱动各部件执行指令。 时间控制:为每条指令提供时序节拍。 数据加工:通过ALU对数据进行算术/逻辑运算。 中断处理:响应外部/内部中断,切换进程。 CPU的基本组成 CPU主要由运算器、控制器、寄存器组和内部总线组成。控制器包括程序计数器(PC)、指令寄存器(IR)、指令译码器、时序产生器和控制逻辑(微程序或硬布线)。 CPU中的主要寄存器 程序计数器(PC):存放下一条指令的地址。 指令寄存器(IR):存放当前正在执行的指令。 累加器(ACC):存放中间运算结果。 状态寄存器(PSW/Flag):存放条件标志(C、Z、N、V)和中断允许等状态。 通用寄存器(R0-Rn):存放操作数和地址。 堆栈指针(SP):指向栈顶地址。 基址/变址寄存器:支持多种寻址方式。 操作控制器与时序产生器 操作控制器产生微操作命令序列,分为微程序控制器(存储微指令)和硬布线控制器(组合逻辑)。时序产生器提供时钟信号和节拍信号,控制指令的执行步骤。 指令周期 指令周期的基本概念 指令周期是指CPU从取指令、译码到执行完一条指令所花的时间。一个指令周期通常包含取指周期(取指令)、间址周期(若需取操作数地址)、执行周期、中断周期(若响应中断)。每个周期又由若干时钟周期(T周期)组成。 MOV指令的指令周期 MOV指令(寄存器间或立即数传送)的指令周期:取指→译码→执行(传送数据)。执行周期只需一个时钟周期(寄存器间)。若MOV涉及内存,则需内存读/写周期。 LAD指令的指令周期 LAD(LOAD)从内存读数据到寄存器:取指→译码→计算地址→读内存→写寄存器。执行周期包括地址计算和内存访问,通常需多个时钟周期。 ADD指令的指令周期 ADD加法指令(寄存器-寄存器):取指→译码→ALU计算→写回结果。执行周期为1个时钟周期。若为内存操作数,则需额外访存周期。 STO指令的指令周期 STO(STORE)将寄存器内容写回内存:取指→译码→计算地址→写内存。写内存通常需要1个周期(假设内存写操作)。 JMP指令的指令周期 JMP无条件跳转:取指→译码→计算目标地址→将目标地址写入PC。执行周期短。条件跳转还需根据标志位决定是否修改PC。 用方框图语言表示指令周期 方框图语言以矩形框表示操作(如“取指令”)、菱形框表示判断(如“是否需要间址”),描述指令周期流程。可以清晰展示微操作序列和时序关系。 时序产生器和控制方式 时序信号的作用和体制 时序信号为CPU各部件提供同步节拍。常见体制:单节拍(所有操作在一个时钟周期完成,限于低速)、多节拍(每条指令分多个时钟周期)、异步(无统一时钟,应答方式)。 时序信号产生器 时序产生器由晶体振荡器(产生主频时钟)、分频器、节拍发生器(环形计数器或分频逻辑)组成。产生时钟周期(T1, T2…)、机器周期(M周期)、指令周期等信号。 控制方式 控制方式指CPU如何发出微操作命令: 同步控制:所有指令使用固定长度的时钟周期。简单但效率低。 异步控制:每条指令或微操作采用应答方式,速度较快但控制复杂。 联合控制:大部分指令同步,少数复杂指令异步扩展。 微程序控制器 微程序控制原理 微程序控制将机器指令(宏指令)解释为一串微指令序列。控制存储器(ROM或RAM)存放微程序。执行指令时,微地址生成器根据指令操作码产生微地址,逐条读取微指令,每个微指令产生一组微操作控制信号。微指令格式分为水平型(一个时钟周期执行多个微操作)和垂直型(类似于机器指令的微指令)。 微程序设计技术 微程序设计技术包括:微指令编码(直接编码、字段直接编码、字段间接编码)、微地址形成(增量、多路转移、下址字段)、微程序顺序控制、微程序设计语言等。现代CPU的微程序常采用加标签的控制存储和分支逻辑。 硬布线控制器 硬布线控制器由组合逻辑电路(门电路、触发器)构成,直接根据指令操作码、时序节拍和状态条件产生控制信号。速度比微程序控制器快,但指令集复杂时逻辑设计极为复杂,不易修改。RISC处理器多采用硬布线控制(也有少数RISC使用微程序)。CISC的早期如8086使用微程序,后来逐步混合。 流水CPU 并行处理技术 并行处理技术包括:指令流水线(时间并行)、多发射(超标量)、多核(空间并行)。流水线将指令执行分解为若干阶段(取指、译码、执行、访存、写回),多个指令重叠执行。 流水CPU的结构 经典五级流水线:IF(取指令)、ID(指令译码/读寄存器)、EX(执行/地址计算)、MEM(访存)、WB(写回)。流水线寄存器(IF/ID、ID/EX、EX/MEM、MEM/WB)用于传递数据和控制信号。流水线需要处理结构冒险、数据冒险和控制冒险。 流水线中的主要问题 结构冒险:资源冲突,如指令和数据共用同一存储器。解决:哈佛结构(指令/数据分离)、增加资源。 数据冒险:后一条指令依赖前一条指令的结果。解决:转发(旁路)、插入气泡(停顿)、编译优化。 控制冒险:分支指令改变PC,导致流水线冲刷。解决:分支预测(静态/动态)、延迟槽(早期RISC)。 现代流水线深度可达10-20级(如Intel Core)。 RISC CPU RISC机器的特点 前面已述。RISC通常采用流水线、单周期指令、LOAD/STORE结构、大量寄存器。典型RISC处理器有ARM、MIPS、RISC-V、PowerPC(早期)等。 RISC CPU实例 ARM Cortex-A系列:多级流水线(通常13级或更少),支持超标量、乱序执行。RISC-V是一个开源指令集,设计简洁,适合教育和嵌入式。 动态流水线调度 动态调度由硬件(如Tomasulo算法)在运行时重排指令顺序,减少数据冒险造成的停顿。需要保留站、重排序缓冲(ROB)和寄存器重命名技术。常见于高性能处理器(Intel Core、AMD Zen)。与之相对的是静态调度(编译器优化)。

September 3, 2025 · 1 min · farmer3-c

指令系统

指令系统的发展与性能要求 指令系统的发展 早期计算机指令非常简单(如单地址、零地址指令)。随着硬件发展和应用需求,指令系统从基本算术逻辑扩展至浮点运算、字符串处理、多媒体(SIMD指令)、加密等。出现了复杂指令集计算机(CISC)和精简指令集计算机(RISC)两种设计哲学。CISC(如x86)指令丰富,便于编程但实现复杂;RISC(如ARM、MIPS)指令精简、规整,易于流水线和高频实现。 指令系统的性能要求 指令系统应满足:完整性(覆盖所有必要操作)、规整性(指令格式简单,寻址方式一致)、高效性(常用指令执行快)、兼容性(软件向前兼容)、可扩展性(便于增加新指令)。此外,还需要支持高级语言、操作系统和并发编程。 低级语言与硬件结构的关系 机器语言(二进制)和汇编语言(助记符)直接对应机器指令,与硬件结构(寄存器、ALU、总线等)紧密相关。程序员通过低级语言可以直接控制硬件资源,但编程效率低。高级语言通过编译或解释转换为目标机器指令,抽象层次更高。 指令格式 操作码 操作码(Opcode)指定指令要执行的操作(如ADD、MOV)。操作码长度可以是定长(便于译码,如RISC通常32位固定长度)或变长(如x86,1-15字节,节省空间但译码复杂)。操作码设计常采用扩展操作码技术,通过预留码点扩展指令数量。 地址码 地址码字段指明操作数的来源和结果的去向。根据地址码数量,指令可分为三地址、二地址、一地址、零地址(如堆栈机)。例如:ADD R1, R2, R3 (R1←R2+R3)为三地址;ADD R1, R2 (R1←R1+R2)为二地址;ADD R1 (ACC←ACC+R1)为一地址。 指令字长度 指令字长度可以是定长(如ARM的32位)或变长(如x86的1-15字节)。定长指令便于取指和译码,适合流水线;变长指令代码密度高,节省内存。现代处理器常采用混合方式:主流RISC为定长32位,CISC使用变长,但在内部转换为类似RISC的微操作。 指令助记符 助记符(Mnemonic)是汇编语言中表示操作码的英文缩写,如ADD、SUB、MOV、JMP。便于记忆和编写。操作数通常使用寄存器符号(如EAX)或立即数、内存地址表达式。 指令格式举例 ARM 32位指令:例如 ADD r0, r1, r2(机器码:E0810002,其中[31:28]条件码,[27:25]为00,[24:21]操作为0100,[20]为S位等)。 x86指令:变长,例如 89 C8 表示 MOV eax, ecx。 操作数类型 一般的数据类型 常见操作数类型:整数(字节、半字、字、双字)、浮点数(单精度/双精度)、字符(ASCII/Unicode)、逻辑数(布尔值)、指针(地址)。 Pentium数据类型 英特尔x86支持:字节(8位)、字(16位)、双字(32位)、四字(64位)、双四字(128位,用于SSE)、10字节扩展浮点数(80位)。也支持BCD(二进制编码十进制)和打包的SIMD数据。 Power PC数据类型 PowerPC(RISC)支持:字节、半字(16位)、字(32位)、双字(64位)。浮点类型为单精度和双精度。支持对齐访问。 指令和数据的寻址方式 指令的寻址方式 指令的寻址即确定下一条指令的地址。顺序执行时,指令地址由程序计数器(PC)自动递增;跳转指令通过偏移量(相对寻址)或绝对地址改变PC值。 操作数基本寻址方式 常见寻址方式: 立即寻址:操作数直接包含在指令中(如 ADD R1, #5)。 寄存器寻址:操作数存放在寄存器中(如 ADD R1, R2)。 直接寻址:指令给出内存地址(如 ADD R1, [1000])。 间接寻址:指令给出存放地址的寄存器或内存单元(如 ADD R1, [R2])。 变址寻址:基址寄存器+偏移量(如 ADD R1, [R2 + 10]),适于数组访问。 相对寻址:PC+偏移量,用于转移指令。 基址寻址:基址寄存器+偏移量,常用于重定位。 堆栈寻址:隐含使用堆栈指针(SP)访问栈顶。 寻址方式举例 以ARM为例:LDR R1, [R2, #8](变址)、LDR R1, [R2, R3](寄存器偏移)、LDR R1, label(PC相对寻址)。x86的 MOV eax, [ebx+ecx*4+8] 复杂变址。 典型指令 ...

September 3, 2025 · 1 min · farmer3-c