您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 软件工程 > 《汇编语言》王爽版学习笔记(精辟的第十一章总结完毕)
《汇编语言》王爽版学习笔记(精辟的第十一章总结完毕)Nisy总坛主UID2198精华69威望8662在线时间2615小时最后登录2010-12-10《汇编语言》王爽版学习笔记(精辟的第十一章总结完毕)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&前言:汇编语言,这个东西我是自学的,所以理解上也是很皮毛,这里简单写下读书写得,文中如有出错之处,还望多多指正。我把这本书分成两部分:前11章为第一部分。后几章涉及到中断等16位操作系统的知识,这儿就不写了,我们只关心前一部分。汇编语言。我是这样理解的:首先他是一套指令集,学习ASM可以站到一个“如何设计处理器、代码如何执行的角度”来看待这套指令集,或者说我们如何通过学习汇编语言来构建一个数据自己涉及的虚拟机平台;期中包括了寄存器的设置、如何将程序模块化==堆栈思想的引用等等。程序,就是内存中的一段数据我们可以将其当做代码也可以当做数据也可以作堆栈来使用所以内存的这些数据如何使用决定权在我们如何去定义我们如何让内存的数据与处理器产生联系并去实现程序员的目的作为要写一本教程,首先要考虑如何将知识讲授给对方。这就是一个将知识系统化并条理化展开的一个过程。前言上有两句话:一个是循序渐进后边的知识后边再讲。这句话很厉害这个思想代表了作者的逻辑,第二句话是编程的平台不是操作系统而是硬件。我们在16的单任务操作系统中可以更专注的了解汇编这门语言解和对C语言的讲解中来尽量去深挖这本书更深层的东西。OK,旅程开始&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&正文:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&前两章:首先介绍了16位的程序如何寻址:段地址+偏移地址。可以找到内存数据后,我们的处理器就有事情来做了。处理器要做的工具就是处理内存的数据,如读取内存的数据、移动内存的数据、对内存的数据做相应的运算(如加减乘除、布尔运算、逻辑移位),我们知道CPU有一些寄存器,那如果不用这些通用寄存器,程序将变成怎样?比如实现一个加法的操作:inti=10,j=20;j+=i;用ASM描述一下:........................................................;**************描述性代码&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***assumecs:code,ds:datadatasegmentidw10jdw20dataendscodesegmentstart:movds,dataaddj,i执行返回代码codeendsendstart;**************描述性代码&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&***........................................................首先,如果CPU内部没有暂时存储器,那我们所有的操作都将直接操作处理内存数据,如果直接操作内存数据,CPU的执行效率将降低,如从内存中COPY数据到加法器中肯定没有从CPU内部传递效率高,资源上本身就是浪费。同时操作上即不方便也将对执行上造成紊乱,如果我们在CPU内部添加一个寄存器,作为一个中间停放站,情况又将会怎样。我们设置一个中间变量ax情况将变成这样:........................................................assumecs:code,ds:datadatasegmentidw10jdw20dataendscodesegmentstart:movax,datamovds,axmovax,iaddax,jmovax,4c00hint21hcodeendsendstart........................................................0BD1:0000B8D00BMOVAX,0BD00BD1:00038ED8MOVDS,AX0BD1:0005A10000MOVAX,[0000]0BD1:000803060200ADDAX,[0002]0BD1:000CB8004CMOVAX,4C000BD1:000FCD21INT21在debug中观看该程序的汇编代码,我们发现变量名其实就相对与数据段的偏移地址。于是我们发现在处理器上添加一个存储空间效果更好一些,当然还有其他原因使创建寄存器更为必要。我们看一下上方这段程序在内存的情况:C:\masm5debugadd.exe-d0BD1:0000B8D00B8ED8A10000-03060200B8004CCD..............L.0BD1:0010215DC3!]..程序就是内存中的一段数据,要处理这些数据,我们首先要知道内存中数据的地址和长度。内存中的代码段,由IP这个寄存器来指向将要执行的代码,而这条指令有多长,处理器通过第一个字节就可以判断出该指令的长度,以实现CPU去正确的执行下一条指令。IP指向的内存数据,首字节为机器码机器码之后是否有数据,跟几个字节的数据,这个要根据机器码来判断且该值是一个固定值。即第一个字节是机器码,之后都是操作数(关于机器码的扩充,一个字节只能存放256中机器码,基本上够用了,将机器码扩充至两个字节的思路就是设置字节中的某位为标志位来作判断)。这也算是汇编指令设计的一个优点--少去了判断所要处理数据长度的麻烦。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&第三章栈机制MOV指令是将数据从一个单元复制到另一个单元,这个单元只可能有三种情况:段寄存器、通用寄存器、内存数据。注意,以下格式是禁止的:内存--内存;内存--段寄存器;段寄存器--段寄存器;寄存器和段寄存器的累加;内存和段寄存器的累加。moves,csmov[0],dsmovds,[0]addes,axaddax,csaddes,[0]add[0],es内存间数据的传递,CPU的指令集中有更便捷的指令代码,今后我们会有接触的。在数据传递中,我们要有格式匹配的意识,即传递字节要相等。下面我们来看几组简单的数据移动指令的机器码:004295A2B800000000MOVEAX,0004295A7BB00000000MOVEBX,0004295ACB900000000MOVECX,0004295B1BA00000000MOVEDX,0可以看到E8E9EAEB是对寄存器传递立即数的机器码004295988BC0MOVEAX,EAX0042959A8BDBMOVEBX,EBX0042959C8BC9MOVECX,ECX0042959E8BC3MOVEAX,EBX004295A08BF7MOVESI,EDI我们这里只想通过这几行代码来简单的了解下机器码的指令集,同时思考下,如果我们设计一套指令集,每条指令对应的机器码会是多少。ADD为加法;SUB为减法;格式和使用上与MOV类似。这里有一个注意点,就是我们在反汇编中看到的代码和源码是有差异的,如:movax,[0]语句在debug中就是将wordptrds;[0]放到ax中,而源码中这样写则是movax,0([0]是十进制的)下面是栈机制,这个栈机制实在是太完美了,假如代码执行上我们不使用栈机制,大家可以试着设计一下如何实现程序的模块化:如寄存器的暂时保存、子程序如何传参、子程序如何返回等问题将如何处理。栈机制这里就不想写了,用过OD的人对这个东西都非常了解。就是有一个栈溢出问题,该问题我们要特别注意一下。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&第四章汇编程序格式assumecs:code,ds:data,ss:stackstacksegmentstackendsdatasegmentdataendscodesegmentstart:movax,4c00hint21hcodeendsendstart编译:masmtest;连接:linktest;debug跟踪调试进入debug后输入个?指令就都有了~~常用的指令:A看代码D看内存E写内存R看寄存器T单步执行遇Call跟进G执行到XX&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&第五章像C一样去学习ASM构造一个循环一个语言,大多通过定义变量来实现对内存数据的处理(变量=内存的地址+长度(变量类型)),然后要有判断和循环语句,这样语言的基本框架就出来了。我们先来看一下在c语言和asm定义变量的区别:---------------------------------------------------所占内存大小:char占一个内存空间定义为:byteint占两个内存空间定义为:word格式:C语言:inta=0x10;A语言:abyte10h定义字符串:C语言:char*s=Hello,Nisy!;A语言:szHellodb'Hello,Nisy!',0==先变量名然后定义类型最后给定数值1.数值项若为空则用?替代2.定义数组,可用ndup(?)---------------------------------------------------我们发现在处理器中加添暂存器(官方叫寄存器)比较方便后,需要考虑应该设置几个寄存器,寄存器用来做些什么的问题。我们再设置两个寄存器:bx和cx,bx用来做偏移地址寻址,cx用来存储循环指令中的次数。(注意哦,AX,BX,CX都是通用寄存器,当他们不做专项功能时,可以随意使用。)BX寄存器还有一种功效:可以用BX来做间接寻址。[BX]默认的段地址为ds数据段。本章第一部分就是来利用CX,LOOP构造循环(记住我们构造的这三个通用寄存器,寄存器不在于多,够用就行)用C来描述一个循环十次的代码:for(intsum=0,i=0;i10;i++){sum++;}for(intsum=0,i=10;i!=0;i--){sum++;}因为汇编中for都用while来替代所以我们用while来实现一下inti=0,sum=0;while(i10){sum++;i++;}while和for的区别初始值(如inti)while前定义好,()内放循环条件,{}中变量自增运算。用汇编翻译一下:movcx,10movax,0@@:incaxloop@@这段代码中涉及到了“标号问题”,同时也告诉了我们一种构建循环的方法。本章第二部分就是:程序有简单推演到复杂的一个逻辑思维过程,程序由一个段扩展为多个段的必然趋势。剩下的内容算是一个扩展,[bx]和loop及当循环体中需利用到CX情况的处理:当循环体中利用到CX时,可以可以将其保存到一个word型变量中,用c描述就是:{intx=i;{把i作为一个空闲内存来处理}i=x;}而汇编中的处理是引入栈机制,我认为栈机制是一个非常巧妙精简的思想,设想下,如果CPU没有栈机制,那我们程序模块化处理时将是如何的费劲,CALL时首先要保存返回地址,其次如何来传递参数……长的结果将导致内存混乱,不堪设想。随便写一段小循环的模型;/////////////////CodeisTest~~By:Nisy///////////////////////assumecs:code,ds:data,ss:stackstacksegmentdw10dup(?)stackendsdatasegmentszHellodb'Hello,Nisy!',0dataendscod
本文标题:《汇编语言》王爽版学习笔记(精辟的第十一章总结完毕)
链接地址:https://www.777doc.com/doc-2843423 .html