指令寄存器

Smali语言基础语法

拥有回忆 提交于 2019-12-02 19:58:14
1、Smali语言基础语法-数据类型与描述符 smali中有两类数据类型:基本类型和引用类型。引用类型是指数组和对象,其它都是基础类型。 基本类型 以及每种类型的描述符: Java类型 类型描述符 说明 boolean Z 布尔型 byte B 字节型 short S 短整型 char C 字符型 int I 整型 long J 长整型 float F 双精度型 void V 返回类型 引用类型 分两种,对象类型与数组类型: 对象类型 表示形式为L包名/对象类型 ; ,即Lpackagename/ObjectName;(注意 分号 ) (1) 开始的L表明这是一个对象类型 (2) packagename 使用"/"代替”.“ (3) ObjectName是对象的名称 (4) 分号表明对象名的结束 例:smali代码中String类型的表示:Ljava/lang/String; 数组类型 以 ‘ [ ’ 数据类型加上 类型描述符 的形式表示: 例:[I 表示一维整型数组,[[I表示二维数组, [Ljava/lang/String; 表示String数组 字段的描述 Davilk中对字段的描述分为两种,对基本类型字段的描述和对引用类型的描述,但是两者的描述格式一样: 对象类型描述符->字段名:类型描述符; 例:com.baidu

精确解释java的volatile之可见性、原子性、有序性(通过汇编语言)

我是研究僧i 提交于 2019-12-02 18:52:00
一、实验环境: 1、Idea代码编辑器 2、jdk1.8.0_92 3、win10_x64 二、易产生误解的Java字段Volatile volatile保证了可见性,但是并不保证原子性!!! 1.volatile关键字的两层语义   一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:   1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。   2)禁止进行指令重排序。 volatile的可见性,即任何时刻只要有任何线程修改了volatile变量的值,其他线程总能获取到该最新值。具体更多实现可以参阅缓存一致性协议。 2.那么volatile为什么又不能保证原子性呢? 以volatile int i = 10;i++;为例分析: i++实际为load、Increment、store三个操作。 某一时刻线程1将i的值load取出来,放置到cpu缓存中,然后再将此值放置到寄存器A中,然后A中的值自增1(寄存器A中保存的是中间值,没有直接修改i,因此其他线程并不会获取到这个自增1的值)。如果在此时线程2也执行同样的操作,获取值i==10,自增1变为11,然后马上刷入主内存。此时由于线程2修改了i的值,实时的线程1中的i==10的值缓存失效,重新从主内存中读取,变为11

《ucore lab1 练习5》实验报告

本秂侑毒 提交于 2019-12-02 15:21:08
[练习5]实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_stackframe来跟踪函数调用堆栈中记录的返回地址。如果能够正确实现此函数,可在lab1中执行 “make qemu”后,在qemu模拟器中得到类似如下的输出: 请完成实验,看看输出是否与上述显示大致一致,并解释最后一行各个数值的含义。 提示:可阅读小节“函数堆栈”,了解编译器如何建立函数调用关系的。在完成lab1编译后,查看lab1/obj/bootblock.asm,了解bootloader源码与机器码的语句和地址等的对应关系;查看lab1/obj/kernel.asm,了解 ucore OS源码与机器码的语句和地址等的对应关系。 要求完成函数kern/debug/kdebug.c::print_stackframe的实现,提交改进后源代码包(可以编译执行) ,并在实验报告中简要说明实现过程,并写出对上述问题的回答。 补充材料: 由于显示完整的栈结构需要解析内核文件中的调试符号,较为复杂和繁琐。代码中有一些辅助函数可以使用。例如可以通过调用print_debuginfo函数完成查找对应函数名并打印至屏幕的功能。具体可以参见kdebug.c代码中的注释。 代码实现 1. 编程前,首先了解下当前情况:在Terminal下输入make

GDB print

邮差的信 提交于 2019-12-02 14:48:34
1.命令格式:print 变量名 简写为: p 变量名 2. print 操作符 @ 是一个和数组有关的操作符,在后面会有更详细的说明。 :: 指定一个在文件或是一个函数中的变量。 {} 表示一个指向内存地址的类型为type的一个对象。 3. 察看内容 全局变量(所有文件可见的) 静态全局变量(当前文件可见的) 局部变量(当前Scope可见的) 如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量。如果此时你想查看全局变量的值时,你可以使用“::”操作符: file::variable function::variable eg: 查看文件f2.c中的全局变量x的值: gdb) p 'f2.c'::x 注:如果你的程序编译时开启了优化选项,那么在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况。对付这种情况时,需要在编译程序时关闭编译优化。GCC,你可以使用“-gstabs” 选项来解决这个问题。 4. 查看数组 (1)动态数组: p *array@len array:数组的首地址,len:数据的长度 eg: (gdb) p *array@len $1 = {2, 4, 6, 8, 10} (2)静态数组 可以直接用print数组名,就可以显示数组中所有数据的内容了。 5. 输出格式 x 按十六进制格式显示变量。 d

速读《深入理解计算机系统》

时光毁灭记忆、已成空白 提交于 2019-12-02 13:04:31
本周速读了《深入理解计算机系统》这本书,这本书从程序员的角度介绍了计算机系统的内在运作,展示了一些本质概念是如何实际的影响应用程序的正确性、性能和实用性的。收获如下: 1、关于进程和线程 进程是操作系统对运行程序的一种抽象,是指计算机中已运行的程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 线程有时被称为轻量级进程,是操作系统能够进行运算调度的最小单位。线程是进程中的一个实体,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源,同一进程中的多个线程之间可以并发执行。 2、几种数据传送指令 movl:传送双字,源操作数指定一个值,可以是立即数,可以存放在寄存器或存储器中。目的操作数指定一个位置,可以是寄存器或存储器地址。 movw:传送两个字节,当一个操作数为寄存器时,必须为下图中八个双字节寄存器元素中的一个。 movb:传递一个字节,当一个操作数为寄存器时,必须为下图中八个单字节寄存器元素中的一个。 movsbl和movzbl负责拷贝一个字节,并设置目的操作数中其余的位。 movsbl的源操作数是单字节的,并将高24位设置为源字节的最高位,然后拷贝到双字的目的中。 movzbl的源操作数是单字节的,在前面加24个0扩展到32位,然后拷贝到双字的目的中。 3、寄存器的使用惯例

8086的7种寻址方式

99封情书 提交于 2019-12-02 12:15:13
七种寻址方式: 1. 立即寻址: 操作数包含在指令中,是指令的一部分。此时的操作数称为立即数 MOV EAX, 1234H 2. 寄存器寻址: 操作数在CPU寄存器中,指令中指定寄存器编号 MOV SI, AX MOV AL, AH 3. 直接寻址: 操作数在存储器中,指令直接包含操作数的有效地址。此时操作数一般存放在数据段DS中,采用换段前缀可以使用其它段寄存器。 MOV AX, [1234H] 4. 寄存器间接寻址: 操作数在存储器中,操作数有效地址在ESI、EDI、EBX、EBP之一种。在不使用换段前缀的情况下, 若有效地址在 SI/DI/BX 中,则以 DS 的值为段值; 若有效地址在 BP 中,则以段寄存器 SS 的值为段值。 MOV AX, [SI] MOV [BP], CX 5. 寄存器相对寻址: 操作数在存储器中,操作数的有效地址是一个基址寄存器(BX、BP)或变址寄存器(SI、DI)内容加上指令中给定的8位或16位位移量之和。即: EA = (BX/BP/SI/DI) + (8/16位位移量) 在不使用换段前缀的情况下,若SI/DI/BX的内容作为有效地址的一部分,则以DS的值为段值;若BP的内容作为有效地址的一部分,则以段寄存器SS的值为段值。 在指令中给定的8位或16位位移量以补码形式表示。在计算有效地址时,若位移量是8位,则将其有符号扩展为16位

操作系统第五章

北战南征 提交于 2019-12-02 06:51:05
输入输出设备分为块设备(硬盘)和字符设备(鼠标,键盘) 硬盘的输入输出以磁盘块(扇区)为单位 鼠标键盘以字符为单位,通过中断机制输入 ----------------------------------------------------------------------------------------------------------------------------------------------- IO设备由 机械部件和电子部件 两部分组成,电子部件就是电路板,也就是IO控制器。IO控制器作为CPU控制IO设备机械部件的中介。它含有控制寄存器(存放CPU命令的参数),状态寄存器(设备是否能进行读写操作),数据寄存器(数据中转站)。由于IO控制器中含有多个寄存器,当CPU发出命令后,IO控制器要进行地址转换(由IO控制器的IO逻辑部分完成),找到对应的寄存器。 IO控制器由三部分组成,分别为 CPU与控制器的接口,IO逻辑,以及控制器与设备的接口 CPU与控制器的接口: 数据寄存器,状态寄存器,控制寄存器位于这里 IO逻辑: CPU 通过控制线告诉IO逻辑指令类型,通过地址线告诉IO逻辑要操作的设备地址,IO逻辑通过访问控制寄存器和状态寄存器得出指令。如果是输出指令的话,IO逻辑将数据寄存器中的数据 转移到 控制器与设备的接口。 控制器与设备的接口:输出命令的话

计算机处理器基础原理笔记

被刻印的时光 ゝ 提交于 2019-12-02 06:43:50
1. 计算机每执行一条指令的过程,可以分解成这样几个步骤。 (1) Fetch (取得指令) ,也就是从PC寄存器里找到对应的指令地址,根据指令地址从内存里把具体的指令,加载到指令寄存器中,然后把PC寄存器自增,在未来执行下一条指令。 (2) Decode (指令译码) ,也就是根据指令寄存器里面的指令,解析成要进行什么样的操作,是MIPS指令集的R、I、J中哪一种指令,具体要操作哪些寄存器、数据或者内存地址。 (3) Execute (执行指令) ,也就是实际运行对应的 R、I、J 这些特定的指令,进行算术逻辑操作、数据传输或者直接的地址跳转。 (4)重复进行(1)~(3)的步骤。 这其实就是一个永不停歇的“Fetch - Decode - Execute”的循环,这个循环称之为 指令周期 (Instruction Cycle)。 在取指令的阶段,指令是放在 存储器 里的,实际上, 通过 PC 寄存器和指令寄存器取出指令的过程,是由控制器(Control Unit )操作的。指令的解码过程,也由控制器进行 。到了执行指令阶段,无论是进行算术操作、逻辑操作的R型指令,还是进行数据传输、条件分支的I型指令,都是由 算术逻辑单元 (ALU)操作的,也就是由 运算器 处理的。不过,如果是一个简单的无条件地址跳转,那么我们可以直接在 控制器 里面完成,不需要用到运算器,如下所示:

多线程volatile关键字

扶醉桌前 提交于 2019-12-02 05:10:47
编译优化 我们都知道,所有的高级程序设计语言所编写的源代码,都要经过编译系统或解释系统的翻译,转换为计算机硬件系统能够识别的机器语言代码,才能最终在计算机上执行。 而现代的编译或解释软件都很强大,很智能,它们会尽可能选择能让我们的程序以最高效率的形式工作,即,它们会尽可能地“优化”我们的代码,使得最终编译或解释出的机器语言代码与我们的源代码有所差异! 这里要涉及计算机存储体系的概念。 计算机存储体系 计算机体统有包括外存、内存等不同的存储层次,相对完整地说。计算机存储体系从“外”到“内”分为5层: 海量外存——存储空间最大,速度最慢; 外存——存储空间大,速度也比较慢; 内存——存储空间不是很大,速度却很快; 高速缓存——存储空间小得多,速度更快; 寄存器——存储空间最小,速度最快; 其实,寄存器已经是CPU的范畴了,它们是CPU不可或缺的组成部分。 在上述存储方式中,最快的是寄存器(组),是CPU指令访问的常客,但是,存储容量非常的少:内存是计算机指令与数据存储的最主要的空间,CPU可以访问内存,但与寄存器比较,对内存的访问速度要慢很多很多。 我们所编写的程序中,变量、数组的本质就是内存空间(无论是系统堆栈还是系统堆),对变量、数组元素的访问,就是对内存的访问。 对于像循环中的控制量 for ( int i = 0 ; i < 10 ; i ++ ) 中的变量i

学 汇编语言 -- 王爽 笔记

删除回忆录丶 提交于 2019-12-02 03:16:49
学 汇编语言 -- 王爽 笔记 -- munds 1: 计算机是由 cpu,内存,外部储存器,主板,等等 组成 2: cpu 通过 数据总线,地址总线,控制总线 来与外部设备交流 3: cpu 通过 统一地址总线 来控制 各大部件 4: cpu 通过 数据总线 接收和发送 数据到 内存 5: 某些cpu 通过 DMA 来控制 速度比较慢的设备 比如 硬盘,软盘,光盘 等 ------------------------------- 废话分割线 ------------------------------------------------------------------------------------------------ cpu 通过各种寄存器来储存临时信息 寄存器有: ax,bx,cx,dx,cs,ds,ss,es cpu运行一条指令的详细动作是 : 1 从cs寄存器中取值 ,2 把给值作为内存地址发送到地址总线上,3 内存器给cpu发送该地址的内容 ,4 cpu处理内容(这个内容就是计算机指令) 在8086中 所有的寄存器都是16位,在 80386 中 所有的寄存器都是 32位 ax,bx,cx,dx 都是 可以分为 al,ah,等的8位寄存器 ax = ah x 2^8 + al cpu可以单独的对 al ,ah等8位寄存器直接操作 cpu