汇编语言程序设计03简单的算术运算与数据传送.ppt
汇编语言程序设计,_03_简单的算术运算与数据传送大连理工大学软件学院_朱明2009年5月31日_ V1.1,第二章提问,如何定义一个字符串变量使其包含10个“hi”?DWORD 12345678h按照小尾顺序存储,如果地址00400050h存储的是34h,那么004000051h和地址00400049h存储的分别是什么?MASM中的标识符需要遵循什么规则?列举MASM中数据类型的三种?MASM汇编语言中的PROC、ENDP和END伪指令分别由什么作用?,汇编语言程序设计-朱明,2,前章回顾,本章程序中的DumpRegs过程 该过程的源代码irvine32.asm中,第404行开始 Macros.inc文件中的第248行开始,简单说一下 mShowRegister使用了宏定义 使用了宏内部变量(LOCAL伪指令定义)使用了字符串变量(”®Name”)使用了OFFSET操作符返回字符串的偏移地址 调用了两个常用的过程(WriteString和WriteHex),分别用来显示字符串和寄存器中的十六进制数,汇编语言程序设计-朱明,3,mShowRegisterEAX,EAXmShowRegisterEBX,EBX,前章回顾,指令系统三种操作数表示方法:,Section 1,操作数类型,汇编语言程序设计-朱明,4,MOV指令,从源操作数向目的操作数复制数据 目的操作数不能够是CS、EIP和IP 操作数不能同为内存操作数(mem)立即数不能直接送段寄存器 操作数尺寸必须相同,汇编语言程序设计-朱明,5,Section 2,movdestination,source,movreg,regmovmem,regmovreg,memmovmem,immmovreg,imm,MOV指令,MOV,从源操作数向目的操作数复制数据 小尺寸操作数复制到大尺寸操作数中的问题 需要判定操作数,然后进行一些适当的处理?如果操作数是负数会怎么样?,汇编语言程序设计-朱明,6,Section 2,movecx,12345678h,ECX?,再将一个WORD送到ecx中,怎么做?,movcx,9999h,CX?,ECX?,movdestination,source,将一个DWORD送到ecx中,怎么做?,MOV指令,MOVZX,零扩展传送 MOVZX只能用于无符号整数 使用0扩展值后 ECX=00009999h,汇编语言程序设计-朱明,7,Section 2,movcx,9999h,9999,5678,1234,CX,ECX,movzxecx,val,9999,5678,1234,CX,ECX,0000,MOV指令,MOVSX,符号扩展传送 MOVSX只能用于有符号整数 使用符号扩展值之后 ECX=FFFFFFF0h 如果CX=-3呢,扩展出来的ECX的结果是多少?,汇编语言程序设计-朱明,8,Section 2,movsxecx,val,1111,1111,1111,0000,1111,.,1111,CX,ECX,1111,1111,1111,0000,MOV指令,MOVSX/MOVZX与MOV的应用比较 用处和原理以及操作目的不同 操作数的范围不同 MOV,5种基本的操作范围 MOVSX、MOVZX,2种基本的操作范围 操作数的属性不同 MOV,要求操作数尺寸必须一致 source和destination的位数必须一致 MOVSX/MOVZX,要求操作数尺寸必须不一致 source必须要比destination小 reg32,reg8/mem8 reg32,reg16/mem16 reg16,reg8/mem8,汇编语言程序设计-朱明,9,Section 2,mem,memmem,immreg,immreg,memreg,reg,reg,memreg,reg,MOV指令,从源操作数向目的操作数复制数据 其中的value1,在汇编完成后是什么?数据?或者其他?使用变量时,隐含着一个寻址的问题直接寻址,汇编语言程序设计-朱明,10,Section 2,movdestination,source,value1DWORD1234hmoveax,value1,A100405000,汇编之后生成的机器码,moveax,value1,MOV指令,直接寻址的过程中的偏移量问题 受篇幅影响程序间的部分内容略,汇编语言程序设计-朱明,11,Section 2,value1BYTE1h,2h,3h,4h,7hmoval,value1,AL=01h,AL=?,moval,value1+4,AL=07h,AL=?,moval,value1+4,AL=07h,AL=?,MOV指令,直接寻址的过程中的偏移量问题 有效地址:在变量的编译地址后面加上一个常数所得到的表示式,例如前面提到的value1+4,称为 采用方括号的方式使用有效地址,就表示需要对有效地址表达式进行寻址以获得该有效地址处的内容 MASM中可以省略掉方括号,上面的两个是等价的 MASM不会对有效地址进行范围检查,因此可能会造成对预定的有效范围之外的数据的访问,汇编语言程序设计-朱明,12,Section 2,moval,value1+4,moval,value1+4,MOV指令,直接寻址的过程中的偏移量问题 在使用16位字或者32位双字以及其他的数据类型的时候,不要忘记对应的偏移量的单位是多少 WORD:2,DWORD:4,汇编语言程序设计-朱明,13,Section 2,value1WORD1h,2h,3h,4h,7hmovax,value1,AX=0001h,AX=?,movax,value1+4,AX=?,AX=0003h,XCHG指令,XCHG,数据交换指令 交换数据,实际上是交换数据在容器中的位置 XCHG指令不能使用立即数作为操作数 XCHG指令不能直接交换两个内存操作数 必须使用至少一个寄存器作为临时存储容器,汇编语言程序设计-朱明,14,Section 2,xchgdestination,source,xchgreg,regxchgmem,regxchgreg,mem,INC、DEC和ADD指令,INC,增指令 DEC,减指令 ADD,将源操作数和目的操作数相加 ADD操作不改变源操作数 ADD的运算结果保存在目的操作数中,汇编语言程序设计-朱明,15,increg/mem,decreg/mem,adddestination,source,Section 2,SUB指令,SUB,将源操作数从目的操作数中减掉 SUB操作不改变源操作数 SUB的运算结果保存在目的操作数中 SUB指令的执行实际上是ADD与补码的运算,汇编语言程序设计-朱明,16,subdestination,source,4-1,4+(-1),+,进位了?,Section 2,NEG指令,NEG,将对应的数字求二进制的补码 负数的补码的求法 将对应的操作数所有位取反然后加一得到,汇编语言程序设计-朱明,17,negreg/mem,-1的补码,+,Section 2,算术综合运算,简单的算术综合运算可以通过前面的指令完成 MOV、ADD、SUB、INC、DEC、NEG其中所有的变量都是32位有符号 假设Xval为26,Yval为30,Zval为40 工程的建立和属性修改部分的内容省略 定义所使用到的各个变量(SDWORD)处理表达式中的子项的值 Xval的取反 将Yval的值复制到寄存器中并减去Zval 最后把各个子项的值相加,汇编语言程序设计-朱明,18,Rval=-Xval+(Yval-Zval),Section 2,标志位的影响,前面讲到过关于EFLAGS的问题 标志位对于结果的判定有重要的作用 CF:判断无符号整数运算是否发生了溢出 OF:判断有符号整数运算是否发生了溢出 SF:判断运算结果是否为负数 仅判定运算结果的最高有效位是否被置位 ZF:判断运算结果是否为零 PF:判断最低字节内的1的个数是否为偶数 AC:判断运算结果的最低有效字节的第3位是否向高位产生了进位,汇编语言程序设计-朱明,19,EFLAGS:由控制CPU的位或者CPU的运算结果的独立位构成CF、OF、SF、ZF、AC、PF,Section 3,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 PF:奇偶标志位,汇编语言程序设计-朱明,20,moval,10001100b,addal,00000010b,subal,10000000b,AL=10001100b,AL=10001110b,AL=00001110b,PF=1,PF=0,Section 3,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 ZF:零标志位,汇编语言程序设计-朱明,21,Section 3,movax,0FFFFh,incax,incax,AX=FFFFh,AX=0000h,AX=0001h,ZF=1,ZF=0,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 SF:符号标志位(最高有效位的判断)符号标志位不区分有符号数和无符号数 不能通过符号位判断是有符号数还是无符号数,汇编语言程序设计-朱明,22,val1WORD0F000hmovax,val1,addax,1,AX=F000h,AX=F001h,SF=1,Section 3,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 SF:符号标志位(最高有效位的判断)符号标志位不区分有符号数和无符号数 不能通过符号位判断是有符号数还是无符号数,汇编语言程序设计-朱明,23,val1WORD0F000hmovax,val1,addax,1,AX=F000h,AX=F001h,SF=1,Section 3,处理器并不能根据数据的定义来正确的设置符号位的CPU并不知道在运算的是有符号数还是无符号数,而数据的类型是程序员的工作,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 AC:辅助进位标志位 是第三位向第四位进位的值,汇编语言程序设计-朱明,24,Section 3,moval,00001111b,addal,00000001b,AL=00001111b,AL=00010000b,AC=1,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 CF:进位(借位呢?)标志位(无符号算术运算)INC和DEC不影响CF标志位 非零整数的NEG操作将设置CF,汇编语言程序设计-朱明,25,val1WORD0FFFFhmovax,val1,incax,AX=0FFFFh,CF=1,Section 3,addax,1,CF=0,negax,CF=1,如果是减法呢?,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 OF:溢出标志位(有符号算术运算)INC和DEC会影响OF标志位,汇编语言程序设计-朱明,26,val1SWORD7FFFhmovax,val1,AX=7FFFh,AX=8000h,OF=1,Section 3,addax,1,incax,OF=1,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 从硬件的角度看OF与CF的判定方法 无符号数的算术运算进位的判定方法?无符号运算,最高位的高一位产生了数据 硬件上的实现非常简单,设多一位的全加器即可 有符号数的算术运算溢出的判定方法?两个正数加法的结果是负数 两个负数相加的结果是正数 两个符号不同的数相加的结果永远不会发生溢出 硬件的判定方法:第6位进位和第7位进位的异或的结果 还记得什么是异或操作么?,汇编语言程序设计-朱明,27,Section 3,标志位的影响,所有的标志位的变化都是在进行算术运算后产生 从硬件的角度看OF与CF的判定方法有符号数的算术运算溢出的判定方法?硬件的判定方法:第6位进位和第7位进位的异或的结果 还记得什么是异或操作么?,汇编语言程序设计-朱明,28,Section 3,+,有进位 1,无进位 0,结果为 1,有溢出了!,标志位的影响,各个标志位的影响因素和判定方法总结 PF:最低字节内的1的个数是否为偶数 ZF:运算结果是否为零 SF:运算结果的最高有效位是否为1 AC:判断运算结果的最低有效字节的第3位是否向高位产生了进位 CF:运算结果的最高有效位的再高一位是否为1 OF:两个操作数的最高位的进位与次高位进位的异或运算的结果 同时需要注意什么样的算术运算能影响那些标志位 尤其要注意NEG、INC、DEC,汇编语言程序设计-朱明,29,Section 3,OFFSET操作符,实模式下的段和地址(半复习)16位段值:16位段偏移 32位保护模式下的段和地址(半复习)16位段选择符:32位段偏移 每个任务的逻辑空间可达64TB,计算方法?OFFSET操作符返回数据标号的偏移地址,汇编语言程序设计-朱明,30,bValBYTE?movesi,OFFSET bVal,ESI=XXXXXXXXh,返回32位地址,Section 4,ALIGN伪指令,ALIGN伪指令可以使指令或变量的位置按照字节、字、双字进行边界对齐 边界值可以是1、2或者是4 对齐可以提高CPU存取内存的效率 变量:填充数据 指令:填充NOP(空指令),汇编语言程序设计-朱明,31,ALIGN边界值,bValBYTE?ALIGN2wValWORD?,增加了对齐伪指令前后wVal变量存储位置的变化,Section 4,PTR操作符,使用PTR操作符对操作数进行尺寸上的重载 功能上相当于C语言中的强制类型转换 PTR操作符不改变操作数的原类型,仅重载新类型,汇编语言程序设计-朱明,32,dValDWORD12345678hmovax,WORD PTR dVal,moveax,dVal,AX=5678h,AX=1234h?AX=5678h?,EAX=12345678h,Section 4,PTR操作符,使用PTR操作符对操作数进行尺寸上的重载 CPU并不在乎你定的数据类型,它只是按照程序定义的规则去访问内存,汇编语言程序设计-朱明,33,dValDWORD12345678hlValWORD1234h,5678hmovax,WORD PTR dVal+1,moveax,DWORD PTR lVal,AX=3456h,Section 4,EAX=56781234h,EAX=?,TYPE操作符,TYPE操作符返回按照字节为单位的元素的大小 BYTE(1)、WORD(2).,汇编语言程序设计-朱明,34,TYPEreg/mem,dValDWORD12345678hlValWORD1234h,5678hmoveax,TYPE dVal,moveax,TYPE lVal,EAX=00000004h,EAX=00000002h,Section 4,Section 4,LENGTHOF和SIZEOF操作符,LENGTHOF操作符返回数组中的元素的个数 只能返回跨行数组第一行的元素的数目 SIZEOF操作符的返回值=LENGTHOF的返回值*TYPE的返回值,汇编语言程序设计-朱明,35,Array1WORD1234h,5678hArray2BYTE20 DUP(?),0moveax,LENGTHOF Array1,EAX=00000002h,moveax,LENGTHOF Array2,EAX=00000015h,LABEL伪指令,LABEL伪指令用于在指定位置插入一个不占用存储空间的、但具有属性特征的标号 相同的存储空间的不同的名字(标号)LABEL也可用于合并成大数,汇编语言程序设计-朱明,36,wValLABELWORDdValDWORD12345678h,78,56,34,12,0001h,0000h,0002h,0003h,wValdVal,Section 4,movax,wVal,ax=5678h,movax,wVal+2,ax=1234h,章节回顾,本章中以下内容是应当掌握 MASM汇编语言的操作数类型 数据传送指令MOV、MOVZX和MOVSX的用法 直接寻址的过程中的偏移量问题 XCHG、INC、DEC和NEG指令的用法 AC、PF、ZF、OF、SF和AC的影响因素和判定条件 OFFSET操作符、ALIGN伪指令、PTR操作符的作用 SIZE操作符和TYPE操作符、LENGTHOF操作符的作用和三者之间的关系 LABEL伪指令的作用,汇编语言程序设计-朱明,37,了解和掌握,问题与回顾,章节回顾,以下的问题我们应当轻松回答 r/m32、imm16分别表示什么?用汇编语言实现类似下面的运算过程 AX=(-wVal1+BX)wval2 连续执行下面指令对于CF、SF、ZF和OF影响分别如何 movax,7FF0h addal,10h addah,1 addax,2 myBytes BYTE 10h,20h,30h,40h 将其前两个字节送入DX寄存中,使其为2010h 将其内容全部传送至EAX寄存器中,汇编语言程序设计-朱明,38,思考问题,本章中的学习了一些指令 如果我们要用这些指令对一个数组进行求和的操作 假设在程序运行之前,数组的大小(5个元素)和元素大小都是已知的(DWORD)要求你的程序仅使用今天以前讲过的指令完成 本道题目作为一个小作业,占总成绩的10%如果是抄书的则不给本次作业的成绩 不可以使用间接寻址等更高级的寻址方式完成 下次课上课之前发送至 姓名_班级_学号,附件形式发送代码,汇编语言程序设计-朱明,39,课后练习,arr1 DWORD 111h,222h,333h,444h,555h,