指令寄存器

第 8 章 内存管理策略

二次信任 提交于 2020-01-06 17:49:11
  为了实现性能改进,应将多个进程保存在内存中,也就是说必须共享内存。 8.1 背景   内存是现代计算机运行的核心。内存由一个很大的字节数组来组成,每个字节都有各自的地址。 8.1.1 基础硬件   CPU可以直接访问的通用存储只有内存和处理器内置的寄存器。   每个进程都有一个独立的内存空间,可以保护进程不会互相影响。 基地址寄存器(base register):最小的合法的物理内存地址。 界限地址寄存器(limit register):指定了范围的大小。   合法范围为(base, base + limit)register   内存空间保护的实现是通过CPU硬件对在用户模式下产生的地址与寄存器的地址进行比较来完成的。   只有操作系统可以通过特殊的特权指令,才能加载基地址寄存器和界限地址寄存器。不允许用户程序修改它们。 8.1.2 地址绑定   源程序中的地址通常是用符号表示的,编译器通常将这些符号地址绑定到可重定位的地址。链接程序或加载程序再将这些可重定位的地址绑定到绝对地址。每次绑定都是从一个地址空间到另一个地址空间的映射。   通常,指令和数据绑定到存储器地址可在沿途任何一步中进行: 编译时 加载时 执行时 8.1.3 逻辑地址空间和物理地址空间   CPU生成的地址通常称为逻辑地址,而内存单元看到的地址(即加载到内存地址寄存器)通常称为物理地址。  

内嵌汇编

[亡魂溺海] 提交于 2020-01-05 09:58:01
参考1、AT&T汇编语言与GCC内嵌汇编简介 2、 Professional.Assembly.Language十三章 ARM GCC 内嵌(inline)汇编手册 内嵌汇编语法如下: __asm__ __volatile__ ( 汇编语句模板: 输出部分: 输入部分: 破坏描述部分 );   汇编语句模板由汇编语句序列组成, 语句之间使用“;”、“\n”或“\n\t”分开 。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1…,%9。指令中使用占位符表示的操作数,总被视为long型(4个字节),但对其施加的操作根据指令可以是字或者字节,当把操作数当作字或者字节使用时,默认为低字或者低字节。对字节操作可以显式的指明是低字节还是次字节。方法是在%和序号之间插入一个字母,“b”代表低字节,“h”代表高字节,例如:%h1。 “__asm__” 表示后面的代码为内嵌汇编,“asm”是“__asm__”的别名。 “__volatile__” 表示编译器不要优化代码,后面的指令保留原样,“volatile”是它的别名。括号里面是汇编指令   C语言关键字volatile(注意它是用来修饰变量而不是上面介绍的__volatile__)表明某个变量的值可能在外部被改变,因此对这些变量的存取不能缓存到寄存器,每次使用时需要重新存取。该关键字在多线程环境下经常使用

初学 Delphi 嵌入汇编[30] - 寄存器表

旧街凉风 提交于 2020-01-05 09:55:56
类型 名称 二进制码 寄存器说明 多功能寄存器 AL 0 累加寄存器低八位 AH 100 累加寄存器低八位 AX 0 16 位累加寄存器 EAX 0 32 位累加寄存器 BL 11 基址寄存器低八位 BH 111 基址寄存器低八位 BX 11 16 位基址寄存器 EBX 11 32 位基址寄存器 CL 1 计数寄存器低八位 CH 101 计数寄存器低八位 CX 1 16 位计数寄存器 ECX 1 32 位计数寄存器 DL 10 数据寄存器低八位 DH 110 数据寄存器低八位 DX 10 16 位数据寄存器 EDX 10 32 位数据寄存器 指针寄存器 SP 100 16 位堆栈指针寄存器 ESP 100 32 位堆栈指针寄存器 BP 101 16位基址指针寄存器 EBP 101 32 位基址指针寄存器 变址寄存器 DI 111 16 位目标变址寄存器 EDI 111 32位目标变址寄存器 SI 110 16 位源变址寄存器 ESI 110 32位源变址寄存器 专用寄存器 IP * 16 位指令指针寄存器 EIP * 32 位指令指针寄存器 FLAGS * 16 位标志寄存器 EFLAGS * 32位标志寄存器 段寄存器 CS 1 代码段寄存器 DS 11 数据段寄存器 ES 0 附加段寄存器 SS 10 堆栈段寄存器 FS 100 标志段寄存器 GS 101 全局段寄存器

volatile的作用

孤街醉人 提交于 2020-01-05 06:26:43
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1). 并行设备的硬件寄存器(如:状态寄存器) 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。 1). 一个参数既可以是const还可以是volatile吗?解释为什么。 2). 一个指针可以是volatile 吗?解释为什么。 3). 下面的函数有什么错误: int square(volatile int *ptr) { return *ptr * *ptr; } 下面是答案: 1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变

c 语言 volatile 关键字

∥☆過路亽.° 提交于 2020-01-05 04:15:16
一.前言 1.编译器优化介绍: 由于内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问。另外在现代CPU中指令的执行并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度。以上是硬件级别的优化。再看软件一级的优化:一种是在编写代码时由程序员优化,另一种是由编译器进行优化。编译器优化常用的方法有:将内存变量缓存到寄存器;调整指令顺序充分利用CPU指令流水线,常见的是重新排序读写指令。对常规内存进行优化的时候,这些优化是透明的,而且效率很好。由编译器优化或者硬件重新排序引起的问题的解决办法是在从硬件(或者其他处理器)的角度看必须以特定顺序执行的操作之间设置内存屏障(memory barrier), Linux 提供了一个宏解决编译器的执行顺序问题。 void Barrier(void) 这个函数通知编译器插入一个内存屏障,但对硬件无效,编译后的代码会把当前CPU寄存器中的所有修改过的数值存入内存,需要这些数据的时候再重新从内存中读出。 2.volatile总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等优化,进一步可以消除一些代码。但有时这些优化不是程序所需要的

C语言中volatile关键字的作用

放肆的年华 提交于 2020-01-05 04:12:32
一.前言   编译器优化介绍:    由于内存访问速度远不及CPU处理速度,为提高机器整体性能, 1)在硬件上: 引入硬件高速缓存Cache,加速对内存的访问。另外在现代CPU中指令的执行并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度。 2)软件一级的优化:一种是在编写代码时由程序员优化,另一种是由编译器进行优化。 编译器优化常用的方法有:将内存变量缓存到寄存器。 由于访问寄存器要比访问内存单元快的多,编译器在存取变量时,为提高存取速度,编译器优化有时会先把变量读取到一个寄存器中;以后再取变量值时就直接从寄存器中取值。但在很多情况下会读取到脏数据,严重影响程序的运行效果。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 二.volatile详解 1.原理作用:   Volatile 意思是“易变的”,应该解释为“直接存取原始内存地址”比较合适。   “易变”是因为外在因素引起的,像多线程,中断等;   C 语言书籍这样定义 volatile 关键字:

volatile变量

一个人想着一个人 提交于 2020-01-04 02:53:53
一、volatile概述 volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址(内存)中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。 volatile一般用于修饰多线程间被多个任务共享的变量和并行设备硬件寄存器等。 二、volatile使用案例 在DSP开发中,经常需要等待某个事件的触发,所以经常会写出这样的程序: 1 short flag; 2 void test() 3 { 4 do1(); 5 while(flag==0); 6 do2(); 7 } 这段程序等待内存变量flag的值变为1,之后才运行do2()。变量flag的值由别的程序更改,这个程序可能是某个硬件中断服务程序。例如:如果某个按钮按下的话,就会对DSP产生中断,在按键中断程序中修改flag为1,这样上面的程序就能够得以继续运行。但是,编译器并不知道flag的值会被别的程序修改,因此在它进行优化的时候,可能会把flag的值先读入某个寄存器,然后等待那个寄存器变为1。如果不幸进行了这样的优化,那么while循环就变成了死循环,因为寄存器的内容不可能被中断服务程序修改。为了让程序每次都读取真正flag变量的值

计算机组成原理——第七章

五迷三道 提交于 2020-01-02 16:28:43
1.指令系统中采用不同的寻址方式的目的是: 缩短指令字长,扩大寻址空间,提高编程灵活性 2.一地址指令中,除地址译码指明的一个操作数外,另一个数用( 隐含寻址 )的方式 4.操作数在寄存器中的寻址方式是(寄存器直接寻址) 5.寄存器间接寻址 方式中,操作数存于( 主存单元 )( 寄存器指明操作数在主存中的地址 ) 7.基址寄存器寻址方式中,操作数的有效地址是( 基址寄存器BR内的值加上形式地址 ) 8.采用基址寻址,基址寄存器内容有 操作系统 确定,在 程序中不能改变 9.采用变址寻址,变址寄存器( IX )内容有用户确定,在程序执行过程中 可以改变 10.堆栈的出栈和入栈操作是相反的,入栈是先 (A)到Msp然后sp-1到sp (注意, 栈顶的地址要比下面的地址都要小 ), 出栈是sp+1到sp,然后再(A)到Msp 13.寻址方式中,立即寻址快于直接寻址快于间接寻址 14.扩展操作码的目的是: 增加指令数(特征位) 16.子程序 调用 指令完整的功能是:( 改变程序计数器的值和堆栈指针sp的值 ) 17.子程序返回指令完整的功能是:( 从堆栈中恢复程序技术器的值 ) 二.填空题 1.在直接寻址中,操作数的有效地址是X,间接寻址中:(X)相对寻址中( PC)+ X ,基址寻址中 (BR)+ X,变址寻址中(IX)+ X 2.条件转移,无条件转移,子程序调用都属于( 程序控制或跳转

DEBUG命令详解

ε祈祈猫儿з 提交于 2020-01-01 12:39:28
DEBUG是DOS中的一个外部命令,从DOS 1.0起就带有此命令,因此可见此命令的重要性了。虽然此命令的功能非常强大,可以解决许多问题,可是对许多人来说,尤其是初学者来说,却非常不易掌握。因此,现将DEBUG的命令详细介绍一番,以让大家知道它的使用。 Debug:A(汇编) 直接将 8086/8087/8088 记忆码合并到内存。 该命令从汇编语言语句创建可执行的机器码。所有数值都是十六进制格式,必须按一到四个字符输入这些数值。在引用的操作代码(操作码)前指定前缀记忆码。 a [address] 参数 address 指定键入汇编语言指令的位置。对 address 使用十六进制值,并键入不以“h”字符结尾的每个值。如果不指定地址,a 将在它上次停止处开始汇编。 有关将数据输入到指定字节中的信息,请单击“相关主题”列表中的 Debug E(键入)。 有关反汇编字节的信息,请单击“相关主题”列表中的 Debug U(反汇编)。 说明 使用记忆码 段的替代记忆码为 cs:、ds:、es: 和 ss:。远程返回的记忆码是 retf。字符串处理的记忆码必须明确声明字符串大小。例如,使用 movsw 可以移动 16 位的字串,使用 movsb 可以移动 8 位字节串。 汇编跳转和调用 汇编程序根据字节替换自动将短、近和远的跳转及调用汇编到目标地址。通过使用 near 或 far

接口与总线 考点整理

删除回忆录丶 提交于 2019-12-29 23:11:06
说明 以下内容为个人整理,答案也是个人回答,不一定对,所以你对答案有任何问题,都欢迎与我讨论。 Q01:51单片机P0、P1、P2、P3口功能作用? 答: P0可做地址口的低8位也可以做数据口和I/O口 P1可做普通的I/O口 P2除了做I/O口,也是作为地址口的高8位(总共16位) P3 既可以是普通IO口,也可以是外部中断、定时、外部输入的端口 Q02:当串口发送一个数据或接收数据时,哪两个位会置位? 答: 接收数据时,RI 会置位 发送数据时,TI 会置位 Q03:81单片机的累加器是什么? 答: ACC Q04:当晶振频率为12MHz,定时器的频率为多少? 答: 频率为1Mhz 说明: 机器频率 = 晶振频率/12 Q05:LED的显示分为几种? 答: 两种,动态扫描和静态扫描 说明: 动态扫描中LED的调度是放在定时器中 Q06:51单片机内存划分 答: 低128个字节 从00H~1FH(32字节):寄存器区,四组寄存器区,一组有8个寄存器 从20H~2FH(16字节 128位):位寻址区 剩下:普通内存 高128个字节 特殊功能寄存器 Q07:ex0、ex1、et0的含义 答: ex0 = 1; //允许外部中断0 ex1 = 1; //允许外部中断1 et0 = 1; //允许定时器0中断 1 2 3 说明: 在这里插入图片描述 上图为IE(中断允许寄存器) EA