chapter5过程_第1页
chapter5过程_第2页
chapter5过程_第3页
chapter5过程_第4页
chapter5过程_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第5章 过程,要点:,MASM库函数 堆栈操作 过程的定义和使用 使用过程进行程序设计,5.2 与外部库链接,链接库是指包含了标准库函数的文件,这些库函数已经编译成机器码的形式。 链接库可以由一个或多个源文件构成,这些文件被汇编成目标文件并以链接器能够识别的特定格式插入到一个文件中构成链接库。 例如:程序要调用WriteString过程在控制台上显示字符串 WriteString PROTO ; PROTO伪指令声明要调用的外部过程, 该语句可以在Irvine32.inc中找到。 Call WriteString ;使用CALL指令调用writestring过程,Call WriteStrin

2、g 指令的处理过程: 汇编器汇编到该指令时,为CALL指令的目的地址留出空白,该地址要等到链接阶段再填入。 链接器在链接库中查找WriteString过程,将其相应的机器指令复制到程序的可执行文件中,并将该过程在可执行文件中的实际地址补入到CALL指令中为目的地址留出的空白处。 如果试图调用的过程不在链接库中,链接器会产生一条链接错误消息,并拒绝生成可执行文件。,链接器的命令行选项 链接程序将程序的目标文件和库文件合并起来,格式为: link32 hello.obj irvine32.lib kernel32.lib irvine32.lib:链接到kernel32.lib库文件。 kerne

3、l32.lib:MS-Windows platform SDK(平台软件开发包)的一部分,链接到kernel32.dll中的操作系统函数。 kernel32.dll:动态链接库,MS-Windows的一个基本组件,包含了字符输入输出等功能的可执行函数。,5.3 本书附带的链接库,控制台窗口:MS-Windows创建的文本窗口,运行于MS-Windows的彩色文本模式下,默认尺寸为80列25行。通过“开始|运行”,“cmd”(for Windows 2000/XP)或”command”(Windows95/98)打开。 标准输入:键盘,也可以重定向到从文件或串口读取。 标准输出:控制台输出,也可

4、以重定向到向文件、打印机或串口输出。 重定向输入输出: 可以在命令行提示符下使用重定向输入输出命令,将标准输入或输出重定向到其他文件或串口。,重定向输入输出命令: 重定向输出 output.txt sample output.txt prog1 | prog2 ;将prog1.exe的输出送到prog2.exe的输入 prog1 output.txt ;prog1.exe从input.txt中读取输入,然后将输出送prog2.exe,prog2.exe再将自己的输出重定向到output.exe. Irvine32.lib链接库中包含的常用过程 P105 表5.1,屏幕显示和光标的变换 Clrs

5、cr:用于清除控制台窗口内容 Crlf:将光标定位到控制台窗口下一行的开始 Gotoxy:将光标定位在控制台窗口中指定的行列位置上。 默认情况下,X坐标范围(列坐标):079,设置在DL中;Y坐标范围(行坐标):024,设置在DH中 例如: mov dh, 10 mov dl, 20 call gotoxy,5.3.2 过程的描述,关于时间 Delay:以指定的毫秒数暂停程序;EAX设置为预期时间间隔,单位是毫秒。例如: mov eax, 1000 call delay GetMseconds:从午夜开始计算的逝去的毫秒数;返回值在EAX中。 .data startTime DWORD ? .

6、code call GetMseconds mov startTime, eax L1: ;(循环体) loop L1 call GetMseconds sub eax, startTime,WaitMsg:显示 “Press Enter to continue ”消息,并等待用户按下回车键。 MsgBox:显示一个图形界面的弹出消息框。调用时通过EDX传递要显示的字符串的偏移地址,字符串将显示在消息框中央,还可以通过EBX传递要显示在标题栏中的字符串的偏移地址。 MsgBoxAsk:显示一个带Yes和NO按钮图形界面的弹出消息框。通过EDX传递要显示的作为问题的字符串的偏移地址,EBX传递显

7、示在标题栏中的字符串的偏移地址。 MsgBoxAsk在EAX中返回一个整数值:IDYES和IDNO,通过该返回值可以知道用户选择了哪个按钮。,从标准输入读入 ReadChar:读取一个字符并在AL中返回,输入的字符不在屏幕上回显。 ReadHex:读取一个32位十六进制整数并在EAX寄存器中返回、对无效字符不进行错误检查。 ReadInt:读入一个32位有符号整数、EAX、进行错误检查、输入的数字可以以正负号开头,但其余部分只能是数字。 ReadString:读入一个字符串,并自动在字符串末尾补入一个空字符作为结束符。EAX中返回字符数、在调用之前需要将EDX设置为指向保存输入字符串的偏移地址

8、、同时将ECX设置为最多可读入的字符数加1。,.data buffer BYTE 21 DUP(0) byteCount DWORD ? .code mov edx, offset buffer mov ecx, sizeof buffer ;设置最多可读入的字符数为sizeof buffer-1 call readstring mov byteCount, eax ;用户输入字符串“ABCDEFG”后,缓冲区buffer的前八个字节 为:41 42 43 44 45 46 47 00 ,此时byteCount的值为7。,ReadDec:读取一个无符号32位十进制整数并在EAX中返回。 Rea

9、dDec将根据读入的字符串设置进位标志: 如果输入的整数字符串为空,则EAX=0, CF=1 如果输入的整数字符串只包含空格,则EAX=0, CF=1 如果输入的整数大于2321,则EAX=0, CF=1 除上述情况之外,EAX=转换后的整数, CF=0,从标准设备输出 WriteBin:以二进制格式显示EAX中的整数的ASCII码。 WriteChar:显示一个字符、调用之前需将字符存储在AL中。 WriteDec:以十进制格式显示一个32位无符号整数,调用之前,需将整数保存在EAX中。 WriteHex:以十六进制格式显示一个32位无符号整数、格式是以8个十六进制的数据位表示,调用之前存入

10、EAX中。 WriteInt:以十进制格式显示一个32位有符号整数、输出的数字开头有符号位,调用之前存入EAX中。 WriteString:显示一个以空字符结尾的字符串,调用之前,将欲显示的字符串的偏移存放在EDX中。,生成随机数 Random32:生成一个32位的随机整数并在EAX中返回。 RandomRange:生成一个0(n1)之间的随机整数在EAX中返回,其中n是通过EAX传递的参数。 例如:生成一个04999之间的随机整数并存放在EAX中 .data randval DWORD ? .code mov eax, 5000 call RandomRange mov randval ,

11、eax Randomsize:初始化在Random32和RandomRange过程的随机数公式中使用的种子值。保证在每次运行程序时,产生的初始随机数都不同。,DumpMem:以十六进制格式显示一块内存的内容。在调用之前,需要将ESI设置为内存开始地址,ECX设置为元素数目,EBX设置为元素尺寸(1=byte, 2=word, 4=doubleword)。 例如:显示一个名为array的包含11个双字变量的数组。 .data array DWORD 1, 2, 3, 4, 5, 6, 7, 8, 9, 0AH, 0BH .code main proc mov esi, offset array

12、mov ecx, lengthof array mov ebx, type array call dumpmem,DumpRegs:以十六进制格式显示CPU通用寄存器、EFLAGS、EIP的内容,并同时显示CF、SF、ZF、OF标志。显示的EIP值是紧跟在call DumpRegs语句后面的指令的偏移地址。 GetCommandTail:将程序的命令行拷贝到一个以空字符结尾的字符串中。如果命令行为空,则设置进位标志,否则清除进位标志。 GetTextColor:返回当前控制台窗口的前景和背景色。返回值在AL中,高4位是背景色,低4位是前景色。 SetTextColor:设置当前输出字符的前景色

13、和背景色。调用前需将欲设置的颜色置于EAX中。,mov eax,white+(blue*16) ;蓝底白字 call SetTextColor ;blue = 0001b white=1111b,OpenInputFile:打开一个已存在的磁盘文件以进行输入,通过EDX传递要打开的文件名的偏移地址。文件是以文件句柄标识的,EAX中返回打开的文件句柄。 ReadFromFile:把输入文件的内容读到一个缓冲区内。EAX传递已打开的文件句柄,EDX传递缓冲区的偏移地址,ECX传递最多读取的字节数。 CloseFile:关闭一个已经打开的文件。如果文件被成功关闭,EAX中返回值为非零值。 Creat

14、OutputFile:创建一个磁盘文件并以输出模式打开。通过EDX传递要创建的文件名的偏移地址。如果文件创建成功,则EAX中返回有效的文件句柄。如果创建失败,EAX中的值是INVALD_HANDLE_VALUE。,GetMaxXY:返回控制台窗口缓冲区的大小。无输入参数,返回时,DL存放窗口缓冲区的列数,DH存放窗口缓冲区的行数。 IsDigit:确定AL中的字符是否是有效的十进制数字(09)。如果AL中的字符是有效的十进制数字,则零标志置位,否则零标志清零。 mov AL, somechar call IsDigit jz digit_found ParseDecimal32:把无符号整数字

15、符串转换为一个32位的二进制数。EDX传递字符串的偏移地址,ECX传递字符串的长度,转换后的二进制值在EAX中返回。 ParseInteger32:把有符号整数字符串转换为一个32位的二进制数。字符串开头可以有加号(表示正数)或负号(表示负数),但符号后必须跟十进制数字。,5.3.3 库测试程序,TITLE Library Test #1:Integer I/O (TestLib1.asm) INCLUDE Irvine32.inc .data arrayD DWORD 1000h,2000h,3000h prompt1 BYTE Enter a 32-bit signed integer:,

16、0 dwordVal DWORD ? .code main PROC mov eax, yellow+(blue*16) call setTextColor call clrscr mov esi, offset arrayD mov ecx, lengthof arrayD mov ebx, TYPE arrayD call DumpMem call Crlf,P116测试程序#1:整数I/O,mov edx, offset prompt1 call WriteString call ReadInt mov dwordVal, eax call Crlf call WriteInt call

17、 Crlf call WriteHex call Crlf call WriteBin call Crlf call WaitMsg mov eax, lightGray+(black*16) call setTextColor call Clrscr exit main ENDP END main,P117 测试程序#2:随机整数 TITLE Link Library Test #2 (TestLib2.asm) INCLUDE Irvine32.inc TAB=9 ;Tab键的ASCII码 .code main PROC call Randomize call Rand1 call Ran

18、d2 exit main ENDP Rand1 PROC mov ecx,10 L1: call Random32 call WriteDec mov al, TAB call WriteChar loop L1 call Crlf ret Rand1 ENDP,Rand2 PROC mov ecx,10 L1: call RandomRange sub eax,50 call WriteInt mov al, TAB call WriteChar loop L1 call Crlf ret Rand2 ENDP END main,P118 测试程序3:性能度量 TITLE Link Libr

19、ary Test #3(TestLib3.asm) INCLUDE Irvine32.inc OUTER_LOOP_COUNT=3 .data startTime DWORD ? msg1 BYTE Please wait.,0dh,0ah,0 msg2 BYTE Elapsed milliseconds:,0 .code main PROC mov edx,OFFSET msg1 call WriteString call GetMSeconds mov startTime,eax mov ecx,OUTER_LOOP_COUNT L1: call innerLoop loop L1,cal

20、l GetMSeconds sub eax,startTime mov edx,OFFSET msg2 call WriteString call WriteDec call Crlf exit main ENDP innerLoop PROC push ecx mov ecx,0FFFFFFFFh L1: mov eax,eax loop L1 pop ecx ret innerLoop ENDP END main,5.4 堆栈操作,堆栈(Stack):后进先出结构(LIFO),遵循新值总是被加到堆栈的顶端,数据也总是从堆栈的最顶端取出的规则。 称内存中分配为执行堆栈操作的内存单元为运行时栈

21、。运行时栈由CPU的SS和ESP寄存器直接管理,用于实现过程调用和过程返回。 SS:堆栈段基址寄存器,存放堆栈在内存中的起始地址。 ESP:堆栈指针寄存器,存放堆栈内某个特定位置的一个32位偏移值;通常由CALL、RET、PUSH和POP等指令间接修改。 ESP总是指向最后压入(或添加)到堆栈上的数据。,压栈操作,Intel采用向下扩展: 32位的压栈(PUSH)操作:将堆栈指针减4,并将值拷贝到 堆栈指针所指向的位置,出栈操作,32位的出栈(POP)操作:从堆栈顶端移走一个值并将其置 于寄存器或变量中;堆栈指针加4,并指向栈中与弹出数据 相邻的最高位置。,堆栈应用程序,在程序中堆栈有几种重要

22、用途: 寄存器在用做多种用途的时候,堆栈可方便地作为临时保存区域,在寄存器使用完后,可恢复其原始值。 CALL指令执行的时候,CPU用堆栈保存当前过程的返回地址。 调用过程的时候,可以通过堆栈传递输入值。 过程内的局部变量在堆栈上创建,过程结束时,这些变量将被丢弃。,压栈和出栈指令,PUSH指令:首先减小ESP的值,然后将一个16位或32位的源操作数拷贝至堆栈上。 对于16位操作数,ESP值将减2;对于32位操作数,ESP将减4。 三种格式: PUSH r/m16 PUSH r/m32 PUSH imm32 如果程序调用Irvine32中的库函数,应总是压入32位值,如果调用Irvine16中

23、的库函数,则可压入16位和32位值。 保护模式下的立即数总是32位的。实地址模式下,如果未使用.386伪指令,默认的立即数是16位的。,POP指令:首先ESP所指的堆栈元素拷贝到16位或32位的目的操作数中,然后增加ESP的值。 对于16位操作数,ESP值将加2;对于32位操作数,ESP将加4。 格式如下: POP r/m16 POP r/m32,PUSHFD/POPFD 对32位EFLAGS进出栈操作 将标志保存在变量中: .data saveflags DWORD ? .code pushfd ;将EFLAGS寄存器的值压入堆栈 pop saveflags ;将ESP所指的堆栈元素拷贝到变

24、量中 从变量中恢复标志值: push saveflags ;将saveflags的值压入堆栈 popfd ;将堆栈顶部的值弹出并送至EFLAGS,PUSHAD/POPAD PUSHAD指令在堆栈上按顺序压入8个32位通用寄存器值:EAX、 ECX、 EDX、 EBX、ESP、EBP、ESI和EDI; POPAD指令以相反顺序从堆栈中弹出这些通用寄存器。 PUSHA/POPA 与上面指令同样的顺序处理16位寄存器,5.4.2.5 反转字符串,RevString.asm程序循环遍历字符串并将每个字符压入堆栈, 然后从堆栈中弹出字符并将其保存在原来的字符变量中。 INCLUDE Irvine32.i

25、nc .data aName BYTE Abraham Lincoln,0 nameSize = ($ - aName) - 1,.code main PROC mov ecx,nameSize mov esi,0 L1: movzx eax, aNameesi ; get character push eax ; push on stack inc esi Loop L1 mov ecx, nameSize mov esi,0 L2: pop eax ; get character mov aNameesi, al ; store in string inc esi Loop L2 mov

26、edx, OFFSET aName call Writestring call Crlf exit main ENDP END main,5.5 过程的定义和使用,PROC伪指令 CALL和RET指令 向过程传递寄存器参数 实例 保存和恢复寄存器 使用过程进行程序设计,PROC伪指令,过程使用PROC和ENDP伪指令来声明,另外还必须给过程起一个名字。 创建除了启动过程之外的其他过程时应以RET指令结束,以强制CPU返回到过程被调用的地方。 启动过程(main)是个特例,它以exit语句结束。,main PROC exit main ENDP,sample PROC ret sample EN

27、DP,CALL和RET指令,CPU总是执行指令指针寄存器EIP所指向的内存地址处的指令。 CALL指令指示处理器在新的内存地址执行指令,以实现对过程的调用; CALL指令将返回地址压入堆栈并将调用过程的地址拷贝到指令指针寄存器中; RET指令使处理器返回到程序中调用过程的地方继续执行; 当程序返回时,RET指令从堆栈弹出地址并送到指令指针寄存器中;,main PROC 00000020 CALL MySub 00000025 mov eax, ebx exit main ENDP Mysub PROC 00000040 mov eax, ebx ret Mysub ENDP,过程的嵌套调用,m

28、ain proc call sub1 exit main endp sub1 proc call sub2 ret sub1 endp sub2 proc call sub3 ret sub2 endp sub3 proc ret sub3 endp,main PROC jmp L2 ;错误 L1: exit main ENDP sub2 PROC L2: jmp L1 ;ok ret sub2 ENDP,局部标号和全局标号,向过程传递寄存器参数,如果过程执行某些诸如整数数组求和之类的操作,一个较好的方法是向过程传递数组的偏移以及数组元素的数目,我们称这些为参数。 例子:P129 整数数组求和

29、,ArraySum过程,从程序接收两个参数:一个指向32位整数数组的指针和一个包含数组元素数目的计数。Arraysum计算数组之和并将其在EAX中返回: ArraySum PROC push esi push ecx mov eax, 0 L1: add eax, esi add esi, 4 loop L1 pop ecx pop esi ret ArraySum ENDP,main调用ArraySum过程,通过ESI传递array的地址,并通过ECX传递数组元素数目,调用之后,将EAX中的和拷贝到一个变量中: .data array DWORD 10000h, 20000h, 30000h

30、, 400000h, 50000h thesum DWORD ? .code main PROC mov esi, offset array mov ecx, lengthof array call ArraySum mov thesum, eax exit main endp end main,保存和恢复寄存器,USES操作符 与PROC伪指令配套使用,用于列出被过程修改的所有寄存器; 它指示编译器做两件事: 在过程的开始处生成PUSH指令在堆栈上保存寄存器; 在过程结束前生成POP指令恢复这些寄存器的值; USES应紧跟PROC伪指令后,其后跟由“空格和制表符”分隔的寄存器列表;,Arra

31、ySum PROC USES esi ecx mov eax, 0 L1: add eax, esi add esi , 4 loop L1 ret ArraySum ENDP 编译器将生成以下代码,ArraySum PROC push esi push ecx mov eax, 0 L1: add eax, esi add esi , 4 loop L1 pop ecx pop esi ret ArraySum ENDP,5.6 使用过程进行程序设计,功能分解或自顶向下设计 实例:整数求和 程序的设计,PromptForIntegers过程调用WriteString函数提示用户输入,然后调用ReadInt函数读取用户输入的整数并将整数保存在ESI所指向的数组中。并循环多次执行此步骤。 ArraySum过程计算整数数组之和并返回。 DisplaySum过程在屏幕上提示一条消息,然后调用WriteInt函数显示EAX寄存器中的整数。,程序的实现:,TITLE Integer Summation Program (Sum2.asm) INCLUDE Irvine32.inc IntegerCount =

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论