汇编语言程序设计04循环控制与过程.ppt

上传人:小飞机 文档编号:6171000 上传时间:2023-10-02 格式:PPT 页数:39 大小:2.37MB
返回 下载 相关 举报
汇编语言程序设计04循环控制与过程.ppt_第1页
第1页 / 共39页
汇编语言程序设计04循环控制与过程.ppt_第2页
第2页 / 共39页
汇编语言程序设计04循环控制与过程.ppt_第3页
第3页 / 共39页
汇编语言程序设计04循环控制与过程.ppt_第4页
第4页 / 共39页
汇编语言程序设计04循环控制与过程.ppt_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《汇编语言程序设计04循环控制与过程.ppt》由会员分享,可在线阅读,更多相关《汇编语言程序设计04循环控制与过程.ppt(39页珍藏版)》请在三一办公上搜索。

1、汇编语言程序设计,_04_循环控制与过程大连理工大学软件学院_朱明2009年5月31日_ V1.1,第三章提问,MOV指令要求源操作数和目的操作数的尺寸必须相同,其功能为将源操作数的值复制到目的操作数中,但有两个源操作数要比目的操作数尺寸小的类似功能的指令是什么?其功能是什么?CF(进位标志位)的判断方法是什么?OF(溢出标志位)的判断方法是什么?SIZEOF操作符、LENGTHOF操作符和TYPE操作符分别返回什么值?三者之间有什么关系?PTR操作符是否会改变操作数的原有类型?保护模式下程序可以访问的最大虚拟内存范围是多少?是如何计算的?什么操作符可取得其段内偏移地址?,汇编语言程序设计-朱

2、明,2,前章回顾,前章一个小题目,10%成绩 如果我们要用这些指令对一个数组进行求和的操作 假设在程序运行之前,数组的大小(5个元素)和元素大小都是已知的(DWORD)要求你的程序仅使用今天以前讲过的指令完成 数组中有5个DWORD类型元素的 如果元素数目和大小未知怎么办?想办法知道元素的数目和大小 建立一个具有判断机制的循环体,汇编语言程序设计-朱明,3,前章回顾,arr1 DWORD 111h,222h,333h,444h,555h,LOOP指令,组成原理实验中的实现循环方法到LOOP循环,汇编语言程序设计-朱明,4,Section 1,AX-1,JC?,AX=初始值,CF(CY),作计数

3、的寄存器,ECX寄存器在与循环指令联合使用时,被自动作为计数器,每次循环之后减去1,标号:正常循环体,ECX=初始值,LOOP 标号,LOOP指令,LOOP指令的执行过程,汇编语言程序设计-朱明,5,标号:正常循环体,ECX=初始值,LOOP 标号,LOOP指令的执行包含两个步骤 ECX的值减1,并与0作比较 如果ECX不等于0,则跳转到对应标号地址处;如果ECX等于0则不跳转 与LOOP指令类似的有使用ECX作计数器的LOOPD和使用CX作为计数器的LOOPW LOOP的跳转范围必须在-128+127字节范围内(Offset=8位有符号)多层嵌套必须考虑好ECX的占用与保存问题,Sectio

4、n 1,JMP指令,无条件段内跳转指令 JMP的跳转是无条件的,同时存在条件跳转指令 JG/JNG,大于则跳转/不大于则跳转 JC/JNC,进位则跳转/不进位则跳转.,汇编语言程序设计-朱明,6,标号:正常循环体,JMP 标号,JMP指令能够实现段内的无条件跳转 段内跳转不代表可以随意跳转 要考虑标号的作用域问题,即每一个标号只能在他所在的过程中(PROC)中可见 可使用全局标号,Section 1,问题处理,程序代码,汇编语言程序设计-朱明,7,TITLESumming of Array;This is a example,loopong controlINCLUDEirvine32.inc

5、.dataarr1DWORD111h,222h,333h,444h,555hval1DWORD?.codemainPROCmoveax,TYPE arr1movval1,eaxmovecx,LENGTHOF arr1moveax,0L1:;把arr1里面元素的值逐一加到一起的方法LOOPL1exitmainENDPENDmain,取得数组相关信息,把数据逐一相加,间接寻址,如何访问下一个数据,Section 1,间接寻址,在第三章中讲过的直接寻址 直接寻址的中存放的直接就是地址/偏移 间接寻址-间接操作数 通过间接操作数寻址时中存放的是寄存器的名称,而该寄存器中保存着数据的地址/偏移 间接寻址

6、中的操作数(寄存器中的值)很容易修改,因此在操作内存中连续的数据(例如数组)时,可实现类似数组下标的功能来访问不同元素,汇编语言程序设计-朱明,8,moval,value1,moval,esi,Section 1,间接寻址,通过间接操作数寻址访问数组 注意要访问的数组元素的大小,汇编语言程序设计-朱明,9,arr2BYTE10h,20h,BYTE30h,40hmovesi,OFFSET arr2moval,esiincesimoval,esiincesimoval,esi,Section 1,假设此时esi=00040500,esi=00040501,10h,20h,30h,40h,00040

7、500,00040501,00040502,00040503,esi=00040502,问题处理,加入间接寻址的方法,汇编语言程序设计-朱明,10,.dataarr1DWORD111h,222h,333h,444h,555hval1DWORD?.codemainPROCmoveax,TYPE arr1movval1,eaxmovecx,LENGTHOF arr1movesi,OFFSET arr1moveax,0L1:addeax,esiaddesi,val1LOOPL1exitmainENDPENDmain,间接寻址,Section 1,使用ESI,问题处理,对于整数数组求和问题的总结与思考

8、 若使用操作数间接寻址则要保存数组的起始偏移地址至某个用于寻址的寄存器中 取得数组种元素的数目并送ECX作为计数器初始值 选择另外一个寄存器用于累加保存结果并将其清零 创建一个用于标示循环体的标号 在循环体中利用操作数间接寻址的方式进行累加操作 修改用于寻址的寄存器,使其指向数组的下一个元素 使用LOOP指令重复执行循环体内容,汇编语言程序设计-朱明,11,Section 1,Section 1,间接寻址,通过间接操作数进行寻址 通过间接操作数寻址时,寄存器中存放的是地址/偏移 通过变址操作数进行寻址 通过变址操作数寻址时,寄存器中不直接存放地址/偏移,而存放一个相对于地址/偏移的增量,汇编语

9、言程序设计-朱明,12,addesi,2moval,esi,movesi,2moval,aar1esi,moval,aar1+esi,间接寻址,通过变址操作数寻址访问数组 注意要访问的数组元素的大小,汇编语言程序设计-朱明,13,arr3BYTE 50h,60h,BYTE 70h,80hmovesi,0moval,arr3+esiaddesi,1moval,arr3+esiaddesi,1moval,arr3+esi,Section 1,esi=0,50h,60h,70h,80h,00040500,00040501,00040502,00040503,假设arr3的存储为,esi=1,esi=

10、2,间接寻址,通过比例因子访问数组 其中的*并不是表示乘法,而是表示比例因子 IA-32处理器支持比例因子的计算方法来计算偏移地址 比例因子通常是数组元素的大小(1、2、4.),可以直接使用TYPE操作符获得元素的大小,汇编语言程序设计-朱明,14,arr4WORD 11h,12h,13hmovesi,2movax,esi*2,Section 1,movax,esi*TYPE arr4,间接寻址,间接寻址另一个应用字符串复制,汇编语言程序设计-朱明,15,t,h,i,.datastr1BYTE“this is the source string”,0str2BYTE(1).codemainPR

11、OCmovecx,(2)movesi,0L1:moval,str1esimov(3),al(4)LOOPL1exitmainENDPENDmain,str1,str2,Section 1,(1)SIZEOF str1 DUP(?),(2)SIZEOF str1,(3)str2esi,(4)inc esi,回顾与练习,关于循环的基本操作练习 编写一个可以实现计算从1开始到1000以内的任意自然数连续相加的汇编语言程序,占成绩10%1+.+MaxVal(MaxVal是一个程序中定义的变量)下次课上课之前发送至姓名_班级_学号,附件形式发送代码 关于循环和间接寻址的一个练习 使用LOOP循环指令和间

12、接寻址实现字符串的逆序复制,汇编语言程序设计-朱明,16,.datastr1BYTE“this is the source string”,0str2BYTESIZEOF str1 DUP(?),回顾与练习,t,h,i,回顾与练习,关于循环和间接寻址的一个练习 使用LOOP循环指令和间接寻址实现字符串的逆序复制,汇编语言程序设计-朱明,17,s,str1,str2,i,n,g,0,g,n,i,s,i,h,t,0,ESI,EDI,回顾与练习,过程的定义,在汇编语言中也有类似高级语言的subroutine机制,称为过程(procedure)过程的定义 过程定义以PROC伪指令开头,以ENDP伪指令

13、结尾 过程定义需要一个有效的标识符作为过程名 被调用过程内应该以RET指令结束,以完成返回;主过程(main)应该以exit结束,汇编语言程序设计-朱明,18,Section 2,sample PROC retsample ENDP,main PROC exitmain ENDP,过程的定义,过程的写法与格式 前面要求的三个过程定义的基本要求 过程的书写在格式上的要求,包含程序的功能说明、需要使用的参数、返回的结果等方面的注释的内容,程序书写上正确的、适合阅读的缩进结构等,汇编语言程序设计-朱明,19,;-SumOf PROC;Calaulates and returns the sum of

14、 three 32-bit integers.;Receives:EAX,EBX,ECX;Return:EAX,saves the sum;-addeax,ebxaddeax,ecxretSumOf ENDP,Section 2,过程的调用,CALL指令指示处理器在新的内存地址执行指令,汇编语言程序设计-朱明,20,call foo,.ret,EIP,00400080,00400020,00400025,00400025,00400020,00400080,EIP被压栈,跳转,Section 2,过程的返回,RET指令从栈中弹出EIP,并按照EIP继续执行程序,汇编语言程序设计-朱明,21,c

15、all foo,.ret,EIP,00400080,00400020,00400025,00400110,00400025,00400020,00400080,00400110,00400025,EIP被压栈,跳转,Section 2,跳转,弹栈为EIP,一个过程在返回之前又调用了其他过程会造成嵌套,PA返回后地址,过程的嵌套,汇编语言程序设计-朱明,22,call PA.,Section 2,call PBret,call PCret,ret,PA返回后地址,PB返回后地址,PB返回后地址PA返回后地址,PC返回后地址,PC返回后地址PB返回后地址PA返回后地址,PB返回后地址PA返回后地址

16、,PA返回后地址,PC返回后地址PB返回后地址PA返回后地址,过程的参数传递,过程中常常需要参数的传递 如果我需要对数组中的N个数求和 每次都通过寄存器传递?要传递若干次 C语言里面怎么做到的?,汇编语言程序设计-朱明,23,;-SumOf PROC;Calaulates and returns the sum of three 32-bit integers.;Receives:EAX,EBX,ECX;Return:EAX,saves the sum;-addeax,ebxaddeax,ecxretSumOf ENDP,Section 2,过程的参数传递,过程中常常需要参数的传递 例如可以传

17、递一个数组偏移和一个元素的数量 数组偏移保存在ESI寄存器中 元素数量保存在ECX寄存器中,汇编语言程序设计-朱明,24,ArraySum PROC;保护现场,压栈moveax,0;清除加法值L1:addeax,esi;执行加法操作addesi,TYPE DWORD;指向下一个整数loopL1;重复循环;恢复现场,弹栈ret;结果保存在EAX中ArraySum ENDP,Section 2,Section 2,过程与堆栈,过程的现场保护实际上就是栈的压栈操作 过程的现场恢复实际上就是栈的弹栈操作 堆栈的操作原则(结构):LIFO 新入栈的数据保存在栈的顶端(小地址),汇编语言程序设计-朱明,2

18、5,PA返回后地址,PA返回后地址,PB返回后地址,PB返回后地址PA返回后地址,PC返回后地址PB返回后地址PA返回后地址,PB返回后地址PA返回后地址,PA返回后地址,PC返回后地址PB返回后地址PA返回后地址,过程与堆栈,堆栈结构与堆栈指针 压栈操作(CALL指令和PUSH指令)堆栈指针ESP始终指向一个有数据的地址/偏移 堆栈指针ESP先修改自身的值(-4),然后再存入数据 IA-32处理器所管理的堆栈中的大地址作为栈底,小地址作为栈顶,汇编语言程序设计-朱明,26,00000FF0,00000FF4,00000FF8,00000FFC,00000006,00001000,压栈前,Se

19、ction 2,ESP,压栈,00000FF0,00000FF4,00000FF8,000000A5,00000FFC,00000006,00001000,压栈后,ESP,过程与堆栈,堆栈结构和堆栈指针 弹栈操作(RET指令和POP指令)对于处理器来说,比堆栈指针地址小的堆栈数据是无效的 堆栈先弹出数据,再修改堆栈指针ESP的指(+4)堆栈的运行是由CPU内部的硬件直接完成的,一般不需要用户修改ESP的值,汇编语言程序设计-朱明,27,00000FF0,00000FF4,00000FF8,000000A5,00000FFC,00000006,00001000,弹栈前,ESP,弹栈,00000F

20、F0,00000FF4,00000FF8,00000FFC,00000006,00001000,弹栈后,ESP,Section 2,过程与堆栈,堆栈的几个重要用途 寄存器在多种用途的时候,堆栈可以作为临时区域方便的临时保存或恢复原有的值 CALL指令执行时,堆栈用于保存其返回地址 在进行过程调用时,可以通过堆栈传递参数 过程内部的局部变量在堆栈上运行,过程结束时放弃 与堆栈操作相关的指令 压栈:CALL、PUSH、PUSHFD、PUSHAD、PUSHA 弹栈:RET、POP、POPFD、POPAD、POPA,汇编语言程序设计-朱明,28,Section 2,过程与堆栈,与堆栈操作相关的指令 P

21、USH reg/mem/imm,将寄存器的值或内存中的值或立即数压入堆栈 PUSHFD,将EFLAGS寄存器的值压入堆栈 PUSHAD,按照由先至后的顺序依次将EAX、ECX、EDX、EBX、ESP的原始值、EBP、ESI和EDI压入堆栈 PUSHA,与PUSHAD同样的顺序将16位寄存器的值压入堆栈 POP reg/mem,将栈顶的值弹出到寄存器或内存中 POPFD、POPAD和POPA分别与对应的PUSHFD、PUSHAD和PUSHA类似,执行弹栈操作,但顺序相反,汇编语言程序设计-朱明,29,Section 2,回顾与练习,关于堆栈和间接寻址的一个练习使用对栈操作和间接寻址实现字符串的逆

22、序复制,30,.datastr1BYTE“this is the source string”,0str2BYTESIZEOF str1 DUP(?),t,h,i,s,str1,汇编语言程序设计-朱明,00000068,00000074,s,i,h,str1,t,回顾与练习,压栈,弹栈,Section 3,过程化程序设计,自上而下的程序设计方法 将大问题分解成为小问题处理 每一个过程都可以进行独立的测试且便于维护 过程之间有明显而简洁的依赖关系 每个过程都更容易解决细节的问题和处理代码的实现 过程化的程序设计以程序的过程作为基本单位 main过程(主过程)DumpRegs过程(用于显示寄存器值

23、的过程)整数求和问题 写一个程序,要求用户从键盘输入3个32位整数,保存在数组中,并计算数组内元素的和并显示在屏幕上,汇编语言程序设计-朱明,31,Section 3,过程化程序设计,自上而下的程序设计方法整数求和问题,汇编语言程序设计-朱明,32,用户输入,系统计算,输出结果,运行流程图,代码结构图,用户输入,系统计算,输出结果,读键盘输入数据,屏幕显示运算结果,主体程序,显示提示,显示提示,Section 3,过程化程序设计,自上而下的程序设计方法整数求和问题,汇编语言程序设计-朱明,33,主体伪代码,main;清除屏幕的内容;用户输入数据过程;提示用户输入;读取用户输入;计算过程;计算机

24、过输出过程;提示结果输出;输出计算结果END main,代码框架,;-main PROC;-exitmain ENDP,;-GetNum PROC;-exitmain ENDP,;-ArraySum PROC;-exitmain ENDP,;-DispSum PROC;-exitmain ENDP,过程化程序设计,自上而下的程序设计方法整数求和问题 完善框架中的代码内容 可能需要的调用一些功能过程 如何在屏幕上显示字符串?如何获取用户输入的数值?如何把计算结果显示在屏幕上?囧rz,其实这些过程不需要自己写的 在irvine32.inc链接库中都提供了这些功能 回顾一下第二章的内容,已经编译成为

25、机器码的链接库是在哪一个阶段和源代码汇编生成的目标文件结合在一起的?,汇编语言程序设计-朱明,34,Section 3,过程化程序设计,在屏幕上显示字符串的过程WriteString 在标准输出上显示一个以空字符结尾的字符串 要显示的字符串的偏移保存在EDX中 获取用户输入的过程ReadInt 从标准输入读取一个32位的有符号数并保存在EAX中,汇编语言程序设计-朱明,35,Str1BYTE“Oh,the beautiful hawaii”,0movedx,OFFSET Str1callWriteString,intValSDWORD?callReadIntmovintVal,eax,Sect

26、ion 3,过程化程序设计,在屏幕上显示计算的结果WriteInt 以十进制的形式在标准输出上输出32位有符号整数 程序中其他功能的过程 输出一个我们意义上的换行,还记得是什么控制符?Crlf:向标准输出上输出0Dh和0Ah两个控制符 清除标准输出的内容,以便用户更好的观察程序输出 Clrscr:通常在程序的开始时候调用 程序中其他可能使用的指令 LOOP、POP以及PUSH相关指令,汇编语言程序设计-朱明,36,moveax,14017088callWriteInt,Section 3,章节回顾,LOOP循环指令的应用方法和跳转要求 无条件跳转指令JMP的用法 操作数间接寻址和变址操作数间接

27、寻址的形式 通过间接寻址实现对数组的访问 过程的定义要求、过程的写法与格式要求 过程的调用和过程的返回,以及对应过程中堆栈的使用情况 堆栈的压栈操作和弹栈操作,以及相关的指令 过程化的程序设计方法及其相关步骤,汇编语言程序设计-朱明,37,章节回顾,章节回顾,以下的问题我们应当轻松回答 IA-32结构中的哪一个寄存器与LOOP联合使用作为计数器?该寄存器中的值为多少时LOOP不再跳转?通过寄存器进行操作数间接寻址和变址操作数间接寻址时,寄存器中应分别保存什么内容?如何定义一个过程的开始以及过程的结束?如何调用一个过程?过程中什么指令表示过程的返回?哪些指令涉及到堆栈的压栈和弹栈操作?保护模式下压栈的过程中,堆栈指针ESP的值和压栈的数据是按照什么顺序变化的?,汇编语言程序设计-朱明,38,章节回顾,思考问题,课后的一个作业 讲义中Page16页的问题 编写一个可以实现计算从1开始到1000以内的任意自然数连续相加的汇编语言程序,占成绩10%下次课上课之前发送至姓名_班级_学号,附件形式发送代码 自己尝试完成 在Page31所提出的问题 参考Page32Page36中所涉及的结构和过程,汇编语言程序设计-朱明,39,思考问题,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号