汇编指令

浅析VS2010反汇编

China☆狼群 提交于 2020-02-29 07:04:36
第一篇 1. 怎样进行反汇编 在调试的环境下,我们能够很方便地通过反汇编窗体查看程序生成的反汇编信息。 例如以下图所看到的。 记得中断程序的运行,不然看不到反汇编的指令 看一个简单的程序及其生成的汇编指令 #include<stdio.h> #include<windows.h> const long Lenth=5060000/5; int main(){ while(true){ for(long i=0;i<Lenth;i++){ ; } Sleep(10); } } 汇编窗体 2. 预备知识 : 函数调用大家都不陌生,调用者向被调用者传递一些參数,然后运行被调用者的代码,最后被调用者向调用者返回结果,还有大家比較熟悉的一句话。就是函数调用是在栈上发生的,那么在计算机内部究竟是怎样实现的呢? 对于程序,编译器会对其分配一段内存。在逻辑上能够分为代码段。数据段,堆,栈 代码段:保存程序文本。指令指针EIP就是指向代码段。可读可运行不可写 数据段:保存初始化的全局变量和静态变量,可读可写不可运行 BSS:未初始化的全局变量和静态变量 堆(Heap):动态分配内存,向地址增大的方向增长。可读可写可运行 栈(Stack):存放局部变量。函数參数,当前状态。函数调用信息等, 向地址减小的方向增长 。很很重要,可读可写可运行 如图所看到的 寄存器 EAX :累加(Accumulator

老赵谈IL(2):CLR内部有太多太多IL看不到的东西,包括您平时必须了解的那些

做~自己de王妃 提交于 2020-02-29 06:39:10
我一直建议大家不要倾向于学习IL的原因有二: IL能够说明的内容太少,包括大部分.NET“必知必会”。 IL能够获得的信息从高级语言中也大都可以知道。 而这篇文章便是希望通过实例来把第1点解释清楚,而第2点则留给下一篇文章来解释。 在文章开始之前,我先要承认两个错误: 首先,上一篇文章对于“IL”和“汇编”的阐述还有些混淆。在这方面某些朋友给出了一些更确切地说法,IL是一种为.NET平台设计的汇编语言,拥有大量.NET平台中特有的高级特性。而x86汇编等则是与机器码一一对应的文字形式代码。不过为了方便表述,在这一系列文章中,还是 以“IL”来指代.NET平台上的中间语言,以“汇编”来指代x86汇编这种和特定CPU平台紧密相关的事物 ——包括之前那篇文章,其实是在阐述IL和汇编之间的关系和区别,以及该如何对待它们的问题,而并非为IL是否可以被叫做是“汇编”进行争论。 其次,在第1篇文章发布的时候,现在这篇文章,也就是本系列第2篇的标题是“汇编可以看到太多IL看不到的东西”。不过后来在半夜重读这篇文章,并且仔细整理这篇文章的示例时发现出了一个问题——我并不是在讲汇编,要探索CLR中的各种问题也并不是仅仅靠汇编来发现的。当时写文章的时候谈了太多的IL和汇编,最终把自己的思路也给绕了进去。现已修改,希望没有给朋友们造成误解,抱歉。今后我也会尽量避免此类情况发生。 好了

分析单片机堆栈,分享个人理解

╄→尐↘猪︶ㄣ 提交于 2020-02-28 18:15:17
看关于单片机方面的书籍的时候,总是能看到别人说的一些堆栈啊什么的操作,之前看到这个术语就直接跳过,没想到去探究单片机内部的原理。但是最近课程学习微机原理这门课,需要我们写汇编程序,汇编里面经常遇到堆栈这个东西,所以就找了个时间把堆栈给彻底的搞一下。 如果了解一点汇编编程话,就可以知道,堆栈是内存中一段连续的存储区域,用来保存一些临时数据。通常用来保存CALL指令调用子程序时的返回地址,RET指令从堆栈中获取返回地址。中断指令INT调用中断程序时,将标志寄存器值、代码段寄存器CS值、指令指针寄存器IP值保存在堆栈中。 堆栈也可以用来保存其他数据。 堆栈操作由PUSH,POP两条指令来完成; 堆栈操作的操作数均为子类型(两个字节)进行操作。 程序内存可以分为几个区,栈区(stack),堆区(Heap),全局区(static),文字常亮区,程序代码区。 程序编译之后,全局变量,静态变量已经分配好内存空间,在函数运行时,程序需要为局部变量分配栈空间,当中断来时,也需要将函数指针入栈,保护现场,以便于中断处理完之后再回到之前执行的函数。 栈是从高到低分配,堆是从低到高分配。 我们一般说的堆栈指的栈。堆栈又分硬堆栈和软堆栈,硬堆栈即SP,从片内RAM的顶部向下生长。软堆栈在硬堆栈跟全局变量区之间的空间,C51函数调用通过R0-R7和栈来实现。 为什么单片机启动时

数据处理的两个基本问题

女生的网名这么多〃 提交于 2020-02-28 06:42:19
总结chapter5-8 这几章分散引入或总结了不少零碎的知识点,包括寻址方式、新增指令用法、伪指令,等等。知识本身难度不大,但是,由于比较零散,也容易给初学者造成困扰。因此,建议对内容进行分门别类梳理、归纳、总结,借助思维导图、表格等形式,让知识结构化、体系化、清晰化。不仅有助于自己学习理解,也有助于后期复习。 第五章[bx]和loop指令在上一篇博客有总结 第六章包含多个段的程序 assume cs:code code segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h mov bx,0 mov ax,0 mov cx,8 s: add ax,cs:[bx] add bx,2 loop s mov ax,4c00h int 21h code ends end "dw"的含义是定义字型数据。 通过ds=0760,可知道程序从0770开始存放,由于数据存放在代码段中,程序运行的时候cs中存放代码段的段地址,所以可以从cs中得到它们的段地址。 用debug加载后,可以将ip设置为10h,从而使cs:ip指向程序中的第一条指令。再用t命令,p命令,或者是g命令执行。 assume cs:code code segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

μC/OS的任务调度实现方法及其在PowerPC上的优化

人走茶凉 提交于 2020-02-27 10:58:01
y = OSUnMapTbl[OSRdyGrp];   SPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);   μC/OS的任务调度算法采用了以空间换时间的策略,将特定字节值的最低位1所在位的信息预先计算并保存到表中,运行时通过查表快速得到;每个任务的TCB中除了保存优先级信息本身外,还使用额外的4个字节保存优先级的高低3位和对应的OSUnMapTbl值,以避免运行时实时计算这几个值所带来的延迟。这些措施增加了系统ROM和RAM的开销。   3 利用 PowerPC “数出前导零数目”指令实现任务调度   PowerPC是Motorola 、IBM和Apple三家公司于20世纪90年代初期联合设计的32位CPU。Freescale(其前身是Motorola半导体部)发展了针对汽车电子的MPC5xx系列单片机及后续基于e200内核的MPC5xxx系列单片机;更高端的e500、e600内核是用于通信领域的MPC6xxx、7xxx和8xxx系列。   下面对μC/OS任务优先级调度算法的改进和优化是在MPC5554单片机上实现的。   PowerPC处理器具有一条“数出前导零数目” 的指令cntlzw(count leading zero word),可以以硬件指令方式实现优先级的多任务调度算法

AtomicReference与volatile的区别

穿精又带淫゛_ 提交于 2020-02-27 08:53:29
首先volatile是java中关键字用于修饰变量,AtomicReference是并发包java.util.concurrent.atomic下的类。 首先volatile作用,当一个变量被定义为volatile之后,看做“程度较轻的 synchronized”,具备两个特性: 1.保证此变量对所有线程的可见性(当一条线程修改这个变量值时,新值其他线程立即得知) 2.禁止指令重新排序 注意volatile修饰变量不能保证在并发条件下是线程安全的,因为java里面的运算并非原子操作。 volatile说明 java.util.concurrent.atomic工具包,支持在单个变量上解除锁的线程安全编程。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入,这只是一种逻辑上的理解。 AtomicReference说明 Java 理论与实践: 正确使用 Volatile 变量 Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized ”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少

王道 第一章 计算机系统概述

那年仲夏 提交于 2020-02-27 07:20:45
这门课学的是逻辑实现,不是具体的机型 主要内容: 基本部件的结构和组织方式 基本运算的操作原理 基本部件和单元的设计思想 运算器:进行 算数运算+逻辑运算 ;一次通常只算两个数字,多个数据计算会拆开,一次运算两个数据 位数多:计算精度越高(小数精确,整数范围大),运算快(一次算64位,在32位机器上要两次,64位机器一次),但是所需的电子器件也多,运算器长度一般是8、16、32、64. 一般来讲,运算器的字长和寄存器、数据总线大小是一样的。如果字长是32位的机器,寄存器和数据总线也都是32. 字长:字长是一个变化的概念,和字节不一样。一个字节是8位二进制。对于64位字长的机器,一个字是64,对于32位字长机器,一个字是32. 控制器 控制器:发号施令的部件,本质就是执行程序,程序由指令构成,取指令、分析指令(译码)、执行指令。保证指令按照规定序列自动连续执行,对异常情况和请求及时响应和处理。 运算器 对于复杂运算,计算机在运算前必须化成多步简单的加减乘除等基本操作来做。每个基本操作就叫做一条指令。而解算某一问题的一串指令序列,叫做该问题的计算程序,简称程序。例如求解二元一次方程,解题步骤的每一步,只完成一种基本操作(一条指令),而整个解题步骤就是一个简单的计算程序。 机器语言和汇编语言都是硬件语言,不同的计算机机器语言和汇编语言是不一样的。汇编和机器语言是一一对应的。

汇编语言-寄存器

╄→гoц情女王★ 提交于 2020-02-26 15:34:22
2.1 通用寄存器 AX, BX, CX, DX 这4个寄存器通常用来存放一般性的数据,被称为通用寄存器。8086CPU这5个寄存器都可以分为两个可以独立使用的8位寄存器来用: AX 可分为 AH 和 AL ; BX 可分为 BH 和 BL ; CX 可分为 CH 和 CL ; DX 可分为 DH 和 DL ; AX 的低8位(0 - 7)构成 AL 寄存器,高8位(8 - 15)构成了 AH 寄存器。 AH 和 AL 寄存器是可以独立使用的8位寄存器。 2.2 字在寄存器中的存储 考虑兼容性8086CPU可以一次性处理一下两种尺寸的数据。 字节 :记为 byte ,一个字节由8个bit组成,可以存在8位寄存器中。 字 :记为 word ,一个字由俩个字节组成,这两个字节分别称为这个字的 高位字节 和 低位字节 。 2.3 几条汇编指令 汇编指令 控制CPU完成的操作 用高级语言表述 MOV ax,18 将18送入寄存器ax ax = 18 ADD ax,8 将寄存器ax中的数值加上8 ah = ax + 8 注意指令的两个操作对象的位数应当是一致的。 例:ax为16位寄存器,只能放4位16进制位数,所以多余的高位会丢失。 2.4 物理地址 CPU访问内存单元时,要给出内存单元的地址。所有内存单元构成的存储空间时一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址

X86汇编2.寄存器

北城余情 提交于 2020-02-26 04:12:47
最近学习了X86汇编,其实无论是古老的8086还是现在i3/5/7/9,Xeon3/5,在最基本原理上,都是相通的,只是CPU位数,寻址空间,寄存器个数,指令集的扩充等方面有所不同,对于学习,8086永不过时。 1.CPU组成 一个典型CPU由:运算器、控制器、寄存器(CPU工作原理)等部件构成,这些器件依靠内部总线连接。 运算器进行信息处理 寄存器进行信息存储,每个CPU有不同数量的寄存器 控制器控制各种器件进行工作 内部总线连接各种器件,在他们之间进行数据的传送 对于一个汇编程序员来说,寄存器是CPU中可以用指令读写的部件,程序员通过改变寄存器中的内容来实现对CPU的控制。 常用的寄存器(reg)有:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di 段寄存器(sreg)有:ds,ss,cs,es 2.通用寄存器 以8086为例,8086CPU的寄存器都是16位的,有4个通用寄存器:AX、BX、CX、DX,但是为了兼容更老的CPU,每个16位通用寄存器可以分为2个8位的独立通用寄存器,如:AX可分成:AH、AL独立使用,其他也一样。 汇编指令(不区分大小写): mov ax, 18 ;将18存入ax寄存器 mov ah, 78 ;将78存入ah寄存器,也就是ax的高8位 add ax, 8 ;将ax寄存器的值加8

X86汇编3.内存访问

老子叫甜甜 提交于 2020-02-26 04:08:25
最近学习了X86汇编,其实无论是古老的8086还是现在i3/5/7/9,Xeon3/5,在最基本原理上,都是相通的,只是CPU位数,寻址空间,寄存器个数,指令集的扩充等方面有所不同,对于学习,8086永不过时。 1.内存中字的存储 8086CPU中,用16位寄存器来存储一个字,高8位存放高字节,低8位存放低字节。在内存中存储时,由于内存单元是字节单元,一个单元存放一个字节,那么一个字(2字节,16位)应该用两个连续的存储单元(内存地址)来存储,低字节存放在低地址,高字节存放在高地址,这就是我们所说的小端序,大端序与之相反。 字单元:存放一个字型数据(16位)的内存单元,它由两个连续内存单元组成。 8086CPU不支持将数据直接存入段寄存器(DS),需要先将数据存放到通用寄存器,然后再MOV到段寄存器。 “[address]”做为一个整体表示一个内存单元,中括号中的数字表示内存单元的偏移地址。如: 假设DS中为1000H,那么: MOV Al, [0] ;将10000H内存地址中的数据存入AX MOV [0], Al ;将AX中的数据存入内存地址10000H eg.1读取10000H中内存单元的内容 mov bx, 1000H mov ds, bx mov al, [0] eg.2将al中的数据存入10000H内存地址中 mov bx, 1000H mov ds, bx mov [0