




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、郑州大学 计算机系 穆玲玲 32位汇编语言程序设计教学重点教学重点堆栈操作堆栈操作子程序设计子程序设计q子程序定义子程序定义q子程序调用和返回子程序调用和返回q参数传递参数传递郑州大学 计算机系 穆玲玲 32位汇编语言程序设计子程序子程序把功能相对独立的程序段单独编把功能相对独立的程序段单独编写和调试,作为一个相对独立的写和调试,作为一个相对独立的模块供程序使用,就形成子程序模块供程序使用,就形成子程序子程序可以实现源程序的模块化,子程序可以实现源程序的模块化,可简化源程序结构,可以提高编可简化源程序结构,可以提高编程效率。程效率。子程序和堆栈的关系十分密切郑州大学 计算机系 穆玲玲 32位汇
2、编语言程序设计7.1 堆栈堆栈 堆栈是一个堆栈是一个“后进先出后进先出FILO”FILO”(或说(或说“先进后先进后出出FILO”FILO”)的主存区域,)的主存区域,位于堆栈段中;位于堆栈段中;SSSS段寄段寄存器存器记录其段地址记录其段地址堆栈只有一个出口,即堆栈只有一个出口,即当前栈顶;用当前栈顶;用堆栈指针堆栈指针寄存器寄存器ESPESP指定指定栈顶是地址较小的一端栈顶是地址较小的一端(低端),栈底不变(低端),栈底不变郑州大学 计算机系 穆玲玲 32位汇编语言程序设计堆栈和队列堆栈和队列堆栈:按照后进先堆栈:按照后进先出出(LIFO)(LIFO)的原则组织的原则组织的存储器空间(栈)
3、的存储器空间(栈)队列:按照先进先队列:按照先进先出出(FIFO)(FIFO)的原则组织的原则组织的存储器空间的存储器空间LIFOFIFO郑州大学 计算机系 穆玲玲 32位汇编语言程序设计堆栈的操作堆栈的操作堆栈只有两种基本操作:进栈和堆栈只有两种基本操作:进栈和出栈,对应两条指令出栈,对应两条指令PUSH和和POPPUSHPUSH;进栈指令先使;进栈指令先使堆栈指针堆栈指针SPSP减减2 2,然后把一个字操然后把一个字操作数存入堆栈顶作数存入堆栈顶部部POPPOP;出栈指令把栈顶;出栈指令把栈顶的一个字传送至指的一个字传送至指定的目的操作数,定的目的操作数,然后堆栈指针然后堆栈指针SPSP加
4、加2 21. 进栈指令进栈指令PUSHP U S H r 1 6 / m 1 6 / s e gP U S H r 1 6 / m 1 6 / s e g;ESPESP-2;ESPESP-2,SS:ESPr16/m16/segSS:ESPr16/m16/segP U S H r 3 2 / m 3 2 / s e gP U S H r 3 2 / m 3 2 / s e g;ESPESP-4;ESPESP-4,SS:ESPr32/m32/segSS:ESPr32/m32/segPUSH immPUSH imm;ESPESP-4;ESPESP-4,SS:ESPimm SS:ESPimm 郑州大学
5、 计算机系 穆玲玲 32位汇编语言程序设计push操作数与寻址操作数与寻址实模式下,堆栈操作的对象只能实模式下,堆栈操作的对象只能是字操作数,采用寄存器或存储是字操作数,采用寄存器或存储器寻址方式。器寻址方式。保护模式下,可以是字和双字操保护模式下,可以是字和双字操作数,采用寄存器,存储器和立作数,采用寄存器,存储器和立即数寻址方式。即数寻址方式。PUSHPUSH指令不影响标志位。指令不影响标志位。 .386.386.model flat, stdcall.model flat, stdcall.stack 4096.stack 4096.data.datavar dword 100var d
6、word 100例7-1(1/2):PUSH指令 .code.codestart:start:push varpush var;mov ax,7812hmov ax,7812hpush axpush ax; retretend startend start例7-1(2/2):PUSH指令 示意图示意图郑州大学 计算机系 穆玲玲 32位汇编语言程序设计例例7-1示意图示意图push varpush varvar dword 100var dword 100堆栈堆栈0012FFC4 ESP0012FFC0 ESP-4-464H00H00H00Hmov ax,7812hmov ax,7812hAX7
7、878 1212push axpush ax0012FFBE ESP-2-278H12H郑州大学 计算机系 穆玲玲 32位汇编语言程序设计2、出栈指令、出栈指令POP P O P r 1 6 / m 1 6 / s e gP O P r 1 6 / m 1 6 / s e g;ESPESP-2;ESPESP-2,SS:ESPr16/m16/segSS:ESPr16/m16/segPOP r32/m32POP r32/m32;ESPESP-4;ESPESP-4,SS:ESPr32/m32SS:ESPr32/m32操作数寻址方式为字量的寄存器和内存操作数寻址方式为字量的寄存器和内存.386.386
8、.model flat , stdcall.model flat , stdcall.data.datad_var dword ?d_var dword ?例7-2(1/2):堆栈指令 .code.codestart:start:push -240push -240mov eax, 1000mov eax, 1000push eax push eax pop bx pop bx pop d_var pop d_var retretend startend start例7-2(2/2):堆栈指令 示意图示意图例例7-2示示意意图图push -240push -240d_vard_var堆栈堆栈0
9、012FFC4 ESP0012FFC0 ESP-4-410HFFHFFHFFHmov eax,1000mov eax,1000push push eaxeax0012FFBC ESP-4-4EAX0000 0000 0303 E8E803HE8Hpop bx pop bx EBX 0303 E8E8 +2+2+4+4pop d_var pop d_var ?00H00H10HFFH0012FFC200H00H0012FFBE郑州大学 计算机系 穆玲玲 32位汇编语言程序设计交换内存数据交换内存数据利用堆栈可以实现两个内存单元利用堆栈可以实现两个内存单元之间的数据交换。之间的数据交换。 var1
10、var2堆栈堆栈ESP.data.datavar1 dword 100var1 dword 100var2 dword 200var2 dword 200.code .code start:start:push var1push var1push var2push var2pop var1pop var1pop var2pop var2例例7-3:交换内存内容交换内存内容 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计堆栈的特点堆栈的特点堆栈操作的单位是字,进栈和出栈只对字量堆栈操作的单位是字,进栈和出栈只对字量字量数据从栈顶压入和弹出时,都是低地址字量数据从栈顶压入和弹出时,都是低地址字
11、节送低字节,高地址字节送高字节字节送低字节,高地址字节送高字节堆栈操作遵循先进后出原则,但可用存储器堆栈操作遵循先进后出原则,但可用存储器寻址方式随机存取堆栈中的数据寻址方式随机存取堆栈中的数据堆栈常用来堆栈常用来q保存和恢复寄存器保存和恢复寄存器q临时存放数据临时存放数据q传递参数传递参数例例7-57-5例例7-47-4push eaxpush eax; ;进入子程序后(或调用子程序前)进入子程序后(或调用子程序前)push ebxpush ebxpush dspush ds.pop dspop ds; ;返回主程序前(或调用子程序后)返回主程序前(或调用子程序后)pop ebxpop eb
12、xpop eaxpop eax例7-4:现场保护与恢复 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计例例7-5将无符号数将无符号数EAX的内容按十进制显示的内容按十进制显示 分析:将无符号数用十进制数显示,分析:将无符号数用十进制数显示,需要对这个数不断地除以需要对这个数不断地除以10,直到,直到商等于商等于0。每一次除法所得到的余。每一次除法所得到的余数就是相应数位上的数值,将它转数就是相应数位上的数值,将它转换成相应换成相应ASCII,即可显示。,即可显示。 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计实例实例例如:例如:EAX=1234, 对对1234不断除以不断除以10,直
13、到商为零为止。直到商为零为止。123410123,余数为,余数为41231012,余数为,余数为312101,余数为,余数为21100,余数为,余数为1将所得到的余数逆序显示。将所得到的余数逆序显示。先将余数依次压入堆栈,然后再依次弹先将余数依次压入堆栈,然后再依次弹出,余数的入栈顺序与出栈顺序相反。出,余数的入栈顺序与出栈顺序相反。.386.386.model flat,stdcall.model flat,stdcallinclude masm32includeio32.incinclude masm32includeio32.inc.stack.stack.data.datastring
14、 byte 10 dup (?)string byte 10 dup (?).code.codestart:start:mov eax , 1234mov eax , 1234mov edi , offset stringmov edi , offset string;edi=string;edi=string的首地址的首地址例7-5:转换十进制字符串 xor edx, edxxor edx, edxxor ecx, ecxxor ecx, ecxmov ebx, 10mov ebx, 10;除数;除数1010a10:div ebxa10:div ebx;edx.eaxedx.eaxebxeb
15、xpush edx;push edx;余数进栈余数进栈inc ecxinc ecx;记录余数个数;记录余数个数xor edx, edxxor edx, edxcmp eax, edxcmp eax, edx;商是否为;商是否为0 0jnz a10jnz a10;商不是;商不是0 0,跳转到,跳转到a10a10例7-5:转换十进制字符串 a20: pop eax;a20: pop eax;商为商为0 0,从堆栈中取出余数,从堆栈中取出余数add al,0add al,0;转换为字符;转换为字符mov edi,almov edi,al;存入;存入ediediinc ediinc edi;修改地址指
16、针;修改地址指针loop a20loop a20;mov byte ptr edi,0mov byte ptr edi,0;字符串以;字符串以0 0结尾结尾WriteString stringWriteString string;显示字符串;显示字符串ret ret end startend start例7-5:转换十进制字符串 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计3通用寄存器入栈指令通用寄存器入栈指令PUSHA/PUSHAD PUSHA;将所有的将所有的16位通用寄存器压入位通用寄存器压入堆栈堆栈 push axpush cxpush dxpush bxpush sp;sp原始
17、值原始值push bppush sipush diPUSHAD;将所有的将所有的32位通用寄存器压入位通用寄存器压入堆栈堆栈 push eaxpush ecxpush edxpush ebxpush esp;esp原始值原始值push ebppush esipush edi郑州大学 计算机系 穆玲玲 32位汇编语言程序设计4. 通用寄存器恢复指令通用寄存器恢复指令POPA/POPAD POPA; ;以与以与PUSHA相反的顺序弹出堆相反的顺序弹出堆栈内容到栈内容到16位通用寄存器中位通用寄存器中 pop dipop sipop bppop sppop bxpop dxpop cxpop ax
18、POPAD; ;以与以与PUSHAD相反的顺序弹出堆相反的顺序弹出堆栈内容到栈内容到32位通用寄存器中位通用寄存器中 pop edipop esipop ebppop esppop ebxpop edxpop ecxpop eax通用寄存器的保护和恢复通用寄存器的保护和恢复pushadpushadpopadpopad郑州大学 计算机系 穆玲玲 32位汇编语言程序设计5标志进栈指令标志进栈指令PUSHF/PUSHFDPUSHFPUSHF;ESPESP-2;ESPESP-2,;SS:ESPFLAGS;SS:ESPFLAGS PUSHFDPUSHFD;ESPESP-4;ESPESP-4,;SS:ES
19、PEFLAGS;SS:ESPEFLAGS可用来保存全部标志位。可用来保存全部标志位。 实模式实模式保护模式保护模式郑州大学 计算机系 穆玲玲 32位汇编语言程序设计6. 标志出栈指令标志出栈指令POPF/POPFD POPFPOPF;FLAGSSS:ESP;FLAGSSS:ESP;ESPESP+2 ;ESPESP+2 POPFDPOPFD;FLAGSSS:ESP;FLAGSSS:ESP;ESPESP+4 ;ESPESP+4 将栈顶内容送入标志寄存器将栈顶内容送入标志寄存器 实模式实模式保护模式保护模式;例例7-6:将:将EFLAGS内容存入内容存入EAX寄存器寄存器pushfd ;保存全部标志
20、到堆栈保存全部标志到堆栈pop eax;从堆栈中取出全部标志从堆栈中取出全部标志标志寄存器操作 ; ;子程序中保存和恢复标志寄存器子程序中保存和恢复标志寄存器pushfdpopfd郑州大学 计算机系 穆玲玲 32位汇编语言程序设计7.2 子程序子程序 子程序是完成特定功能的一段程子程序是完成特定功能的一段程序序当主程序(调用程序)需要执行当主程序(调用程序)需要执行这个功能时,采用这个功能时,采用CALL调用指令调用指令转移到该子程序的起始处执行转移到该子程序的起始处执行当运行完子程序功能后,采用当运行完子程序功能后,采用RET返回指令回到主程序继续执行返回指令回到主程序继续执行郑州大学 计算
21、机系 穆玲玲 32位汇编语言程序设计主程序与子程序主程序与子程序CALL label主程序主程序RET子程序子程序回到回到CALL指令后的指令指令后的指令处处返回地址返回地址郑州大学 计算机系 穆玲玲 32位汇编语言程序设计7.2.1过程定义伪指令过程定义伪指令 过程名过程名 PROC PROC 属性属性 语言类型语言类型 可见性可见性 USES USES 寄存器列表寄存器列表 , ,形参形参 :类型类型. ; ; 过程体过程体过程名过程名 ENDPENDPn过程名过程名(子程序名)为符合语法的标识符(子程序名)为符合语法的标识符郑州大学 计算机系 穆玲玲 32位汇编语言程序设计过程属性过程属
22、性(1)过程属性分为过程属性分为NEAR或或FAR qNEAR属性的过程只能被相同代码段的属性的过程只能被相同代码段的其他程序调用,为段内近调用;其他程序调用,为段内近调用;qNEAR16/NEAR32 NEAR16/NEAR32 qFAR属性属性的过程可以被相同或不同代的过程可以被相同或不同代码段的程序调用,为段间远调用。码段的程序调用,为段间远调用。q FAR16/FAR32 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计过程属性过程属性(2)3 2 位 的 程 序 会 自 动 选 择位 的 程 序 会 自 动 选 择 F A R 3 2 或或NEAR32; 16位的程序会自动选择位的
23、程序会自动选择NEAR16和和FAR16qtinytiny、smallsmall、compactcompact存储下,过程的缺省存储下,过程的缺省属性为属性为near16;qmediummedium、largelarge和和hugehuge存储模式下,过程的存储模式下,过程的缺省属性为缺省属性为far16。qflatflat模式下,过程的缺省属性为模式下,过程的缺省属性为nearnear32。郑州大学 计算机系 穆玲玲 32位汇编语言程序设计语言类型语言类型 语言类型说明标识符的命名规则语言类型说明标识符的命名规则和子程序的调用规则,可以是和子程序的调用规则,可以是C,STDCALL,SYSC
24、ALL,PASCAL。郑州大学 计算机系 穆玲玲 32位汇编语言程序设计表7-1 MASM 6.x的语言类型语言类型CSYSCALLSTDCALLPASCALBASICFORTRAN命名约定名字前加下划线 名字前加下划线名字变大写名字大写名字大写参数传递顺序从右到左从右到左从右到左从左到右从左到右从左到右平衡堆栈的程序调用程序被调用程序被调用程序被调用程序被调用程序被调用程序保存BP 是是是允许VARARG参数是是是 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计可见性可见性 可见性决定子程序是否能被其他可见性决定子程序是否能被其他模块使用。其选项有模块使用。其选项有PRIVATE,PUB
25、LIC,和和EXPORT。默认选项是默认选项是PUBLIC。 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计USES USES项指定子程序中使用的寄存项指定子程序中使用的寄存器,汇编程序会根据这个选项自器,汇编程序会根据这个选项自动生成子程序开始和结束时相应动生成子程序开始和结束时相应寄存器的保存和恢复代码。寄存器的保存和恢复代码。 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计形参表形参表 形参表是子程序需要的入口参数,形参表是子程序需要的入口参数,参数的类型可以是参数的类型可以是WORD,DWORD等,也可以是等,也可以是VARARG。郑州大学 计算机系 穆玲玲 32位汇编语言程序
26、设计7.2.2 子程序调用和返回指令子程序调用和返回指令 子程序调用指令子程序调用指令CALL 子程序返回指令子程序返回指令RET CALL和和RET指令均不影响标志位。指令均不影响标志位。 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计1、子程序调用指令、子程序调用指令CALL CALL label;段内调用,直接寻址段内调用,直接寻址;ESPESP-4,SS:ESPEIP,;EIPEIP+32位位移量位位移量CALL r32/m32;段内调用,间接寻址:段内调用,间接寻址:ESPESP-4,SS:ESPEIP,;EIPr32/m32CALL far ptr label;段间调用,直接寻
27、址:段间调用,直接寻址:ESPESP-2,SS:ESPCS,;ESPESP-4,SS:ESPEIP,;EIPlabel偏移地址,偏移地址,CSlabel段地址段地址CALL far ptr mem;段间调用,间接寻址段间调用,间接寻址:ESPESP-2,SS:ESPCS,;ESPESP-4,SS:ESPEIP,;EIPmem,CSmem+4汇编程序可以自动确定是段内还是段间调用汇编程序可以自动确定是段内还是段间调用; ;也可以采用也可以采用near ptr或或far ptr操作符强制成操作符强制成为近调用或远调用。为近调用或远调用。 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计2、子程序
28、返回指令、子程序返回指令RET RET;无参数段内返回无参数段内返回;EIPSS:ESP,ESPESP+4RET i8;有参数段内返回有参数段内返回EIPSS:ESP,ESPESP+4,;ESPESP+i8RET;无参数段间返回无参数段间返回EIPSS:ESP,ESPESP+4,;CSSS:ESP,ESPESP+2RET i8;有参数段间返回:有参数段间返回:EIPSS:ESP,ESPESP+4,;CSSS:ESP,ESPESP+2,ESPESP+i8郑州大学 计算机系 穆玲玲 32位汇编语言程序设计返回指令返回指令RET的参数的参数RET i8;有参数返回;有参数返回RET指令可以带有一个立
29、即数指令可以带有一个立即数i8,则堆栈指针则堆栈指针ESP将增加,即将增加,即ESPESP+i8这个特点使得程序可以方便地清除若这个特点使得程序可以方便地清除若干执行干执行CALL指令以前入栈的参数指令以前入栈的参数郑州大学 计算机系 穆玲玲 32位汇编语言程序设计子程序实例子程序实例例例7-7:7-7:十六进制数转换为字符十六进制数转换为字符例例7-8:7-8:把把AL内容转换为十六进制字符串内容转换为十六进制字符串例例: :把把EAX内容转换为十六进制字符串内容转换为十六进制字符串郑州大学 计算机系 穆玲玲 32位汇编语言程序设计例例7-7 利用子程序完成将利用子程序完成将AL低低4位中的
30、一位中的一位位16进制数转换成对应的进制数转换成对应的ASCII码码 ; ;主程序主程序mov al,0fhmov al,0fh ; ;提供参数提供参数ALALcall htoasccall htoasc; ;调用子程序调用子程序retret例例7-7 htoasc prochtoasc procand al,0fhand al,0fh; ;只取只取alal的低的低4 4位位or al,30hor al,30h;al;al高高4 4位变成位变成3 3cmp al,39hcmp al,39h ; ;是是0909,还是,还是AFAFjbe htoendjbe htoendadd al,7add a
31、l,7; ;是是AFAF,其,其ASCIIASCII值还要加上值还要加上7 7retret; ;子程序返回子程序返回htoasc endphtoasc endp例例7-7 :子程序子程序郑州大学 计算机系 穆玲玲 32位汇编语言程序设计例例7-8:AL内容转换为十六进制字符串内容转换为十六进制字符串分析:分析:ALAL中中8 8位二进制数对应位二进制数对应2 2位十六位十六进制数,先转换高进制数,先转换高4 4位成位成ASCIIASCII码并保码并保存,然后转换低存,然后转换低4 4位并保存。位并保存。 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计例例7-8:AL内容转换为十六进制字符串
32、内容转换为十六进制字符串如果子程序要使用某些寄存器,但又如果子程序要使用某些寄存器,但又不能改变其原来的内容不能改变其原来的内容q在过程开始部分先将要修改内容的寄存在过程开始部分先将要修改内容的寄存器顺序压栈(不包括返回值寄存器)器顺序压栈(不包括返回值寄存器)q在过程最后返回调用程序之前,再将这在过程最后返回调用程序之前,再将这些寄存器内容逆序弹出些寄存器内容逆序弹出 .data .dataHexStr byte 2 dup(?);HexStr byte 2 dup(?);保存字符串保存字符串 .code.codemov edi, offset HexStr ;edi=stringmov e
33、di, offset HexStr ;edi=string首地址首地址ALsaveALsaveproc ;proc ;实现实现alal内容的显示内容的显示 ; ;过程中使用了过程中使用了EAXEAX、ECXECX和和EDXEDX push eax push eax push ecx push ecx push edx push edx push eax ; push eax ;暂存暂存alal例例7-8 mov dl,al ;mov dl,al ;转换转换alal的高的高4 4位位mov cl,4mov cl,4shr dl,clshr dl,clor dl,30h ;alor dl,30h
34、;al高高4 4位变成位变成3 3cmp dl,39hcmp dl,39hjbe alsave1jbe alsave1add dl,7add dl,7; ;是是0Ah0Fh0Ah0Fh,其,其ASCIIASCII码还要加上码还要加上7 7alsave1:mov edi, dlalsave1:mov edi, dl; ;保存字符保存字符例例7-8 pop edxpop edx; ;恢复原恢复原axax值到值到dxdxand dl,0fhand dl,0fh ; ;转换转换alal的低的低4 4位位or dl,30hor dl,30hcmp dl,39hcmp dl,39hjbe alsave2j
35、be alsave2add dl,7add dl,7inc ediinc edi; ;修改地址指针修改地址指针例例7-8 alsave2:mov edi, dlalsave2:mov edi, dl; ;显示显示 pop edxpop edx pop ecx pop ecx pop eax pop eax ret ret; ;过程返回过程返回ALsaveALsaveendpendp例例7-8 .386.386.model flat,stdcall.model flat,stdcallinclude masm32includeio32.incinclude masm32includeio32.i
36、nc.data.dataHexStr byte 8 dup(?),0 HexStr byte 8 dup(?),0 ;32;32位二进制数对应的十六进制字符共有位二进制数对应的十六进制字符共有8 8个个.code.code把把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 start:start:ReadUDecDword eaxReadUDecDword eax; ;从键盘接受一个从键盘接受一个3232位的十进制数位的十进制数mov edi,offset HexStr mov edi,offset HexStr ;edi=HexStr;edi=HexStr的首地址的首地址
37、mov ecx, 4mov ecx, 4把把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 eaxsave:rol eax,8 ;eaxsave:rol eax,8 ;从高位开始转换从高位开始转换call ALsave ;call ALsave ;调用转换过程调用转换过程add edi,2 ;add edi,2 ;修改存放字符串的地址指针修改存放字符串的地址指针loop eaxsaveloop eaxsave ; ;调用程序段结束调用程序段结束WriteString HexStr WriteString HexStr ; ;显示转换后的字符串显示转换后的字符串ret ;re
38、t ;程序结束,返回操作系统程序结束,返回操作系统 把把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 Alsave proc ;Alsave proc ;实现实现alal内容的转换内容的转换; ;过程中使用了过程中使用了EAXEAX、ECXECX和和EDXEDXpush eaxpush eax push ecxpush ecxpush edxpush edxpush eaxpush eax ; ;暂存暂存axax把把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 mov dl,al ;mov dl,al ;转换转换alal的高的高4 4位位mov cl
39、,4mov cl,4shr dl,clshr dl,clor dl,30h ;alor dl,30h ;al高高4 4位变成位变成3 3cmp dl,39hcmp dl,39hjbe alsave1jbe alsave1add dl,7add dl,7; ;是是0Ah0Fh0Ah0Fh,其,其ASCIIASCII码还要加上码还要加上7 7把把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 alsave1:mov edi,dlalsave1:mov edi,dl ; ;保存高四位保存高四位pop edxpop edx ; ;恢复原恢复原axax值到值到dxdxand dl,0
40、fh ;and dl,0fh ;转换转换alal的低的低4 4位位or dl,30hor dl,30hcmp dl,39hcmp dl,39hjbe alsave2jbe alsave2add dl,7add dl,7把把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 alsave2:mov edi+1, dlalsave2:mov edi+1, dl ; ;保存低四位保存低四位pop edxpop edxpop ecxpop ecxpop eaxpop eaxretret ; ;过程返回过程返回ALsaveALsaveendpendpend startend start把
41、把EAX寄存器内容转寄存器内容转换为十六进制字符串换为十六进制字符串 ALsaveALsaveproc uses eax ecx edxproc uses eax ecx edx; ;实现实现alal内容的转换内容的转换;去掉保存寄存器语句;去掉保存寄存器语句push eaxpush eax; ;暂存暂存axax;与例;与例7-87-8中相同中相同; ;去掉恢复寄存器语句去掉恢复寄存器语句retret; ;过程返回过程返回ALsaveALsaveendpendpend startend startUSES 伪指令伪指令 ; ;自动在子程序开始的地方加入保存寄存器的自动在子程序开始的地方加入保存
42、寄存器的语句:语句:push eaxpush ecxpush edx; ;在子程序结束的地方自动加入恢复寄存器的在子程序结束的地方自动加入恢复寄存器的语句:语句:pop edxpop ecxpop eax汇编汇编USES伪指令伪指令 ALsaveALsaveproc uses eax ecx edxproc uses eax ecx edx; ;实现实现alal内容的转换内容的转换;去掉保存寄存器语句;去掉保存寄存器语句push eaxpush eax; ;暂存暂存axax;与上例中相同;与上例中相同; ;去掉恢复寄存器语句去掉恢复寄存器语句retret; ;过程返回过程返回ALsaveALs
43、aveendpendpend startend startUSES 伪指令伪指令 ; ;自动在子程序开始的地方加入保存寄存器的自动在子程序开始的地方加入保存寄存器的语句:语句:push eaxpush eaxpush ecxpush ecxpush edxpush edx; ;在子程序结束的地方自动加入恢复寄存器的在子程序结束的地方自动加入恢复寄存器的语句:语句:pop edxpop edxpop ecxpop ecxpop eaxpop eax汇编汇编USES伪指令伪指令 郑州大学 计算机系 穆玲玲 32位汇编语言程序设计7.2.3 子程序的参数传递子程序的参数传递 入口参数入口参数(输入参
44、数)(输入参数)q主程序提供给子程序主程序提供给子程序出口参数出口参数(输出参数)(输出参数)q子程序返回给主程序子程序返回给主程序参数的形式:参数的形式: 数据本身(传值)数据本身(传值) 数据的地址(传址)数据的地址(传址)传递的方法:传递的方法: 寄存器寄存器 变量变量 堆栈堆栈把参数存于约定的寄存器中,可以传把参数存于约定的寄存器中,可以传值,也可以传址。值,也可以传址。子程序对带有出口参数的寄存器不能子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护和恢复(主程序视具体情况进行保护)保护)子程序对带有入口参数的寄存器可以子程序对带有入口参数的寄存器可以保护,也可以不
45、保护;但最好一致保护,也可以不保护;但最好一致入口参数:入口参数:ECX元素个数,元素个数,EBX数组偏移地址数组偏移地址出口参数:出口参数:EAX校验和校验和用寄存器传递参数用寄存器传递参数郑州大学 计算机系 穆玲玲 32位汇编语言程序设计例例7-9 :求校验和求校验和设设array是是10个元素的数组,每个个元素的数组,每个元素是双字数据。试用子程序计算元素是双字数据。试用子程序计算数组元素的校验和,并将结果存入数组元素的校验和,并将结果存入变量变量result中。中。“校验和校验和”是指不记进位的累加和是指不记进位的累加和. .386.386.model flat , stdcall.m
46、odel flat , stdcall.stack.stack.data.datacountcountequ 10equ 10; ;数组元素个数数组元素个数arrayarraydword dword 3212h,25h,023f0h,012a3h,3,68h,1271h,3212h,25h,023f0h,012a3h,3,68h,1271h,0ca00h,0ff00h,90h0ca00h,0ff00h,90h; ;数组数组resultresultdword ?dword ?; ;校验和校验和例例7-9 .code.codestart:start:; ;设置入口参数设置入口参数mov ebx,o
47、ffset arraymov ebx,offset array;EBX;EBX数组的偏移地址数组的偏移地址mov ecx,countmov ecx,count;ECX;ECX数组的元素个数数组的元素个数call checksumcall checksum; ;调用求和过程调用求和过程mov result,eaxmov result,eax; ;处理出口参数处理出口参数ret ret 例例7-9 ;计算字节校验和的通用过程计算字节校验和的通用过程;入口参数:入口参数:; ;EBX=数组的偏移地址,数组的偏移地址,ECX=元素个数元素个数;出口参数:出口参数:EAX=校验和校验和;说明:除说明:除
48、EAX/EBX/ECX外,不影响其他寄存外,不影响其他寄存器器例例7-9 checksumchecksum procprocxor eax,eaxxor eax,eax; ;累加器清累加器清0 0suma:suma:add eax,ebxadd eax,ebx; ;求和求和add ebx,4add ebx,4; ;指向下一个数据指向下一个数据loop sumaloop sumaretretchecksumchecksum endpendpend startend start例例7-9 主程序和子程序直接采用同一个主程序和子程序直接采用同一个变量名共享同一个变量,实现参变量名共享同一个变量,实现
49、参数的传递数的传递不通模块间共享时,需要声明不通模块间共享时,需要声明子程序子程序eaxsave入口参数:入口参数:result=要显示的要显示的32位数据位数据HexStr=字符缓冲区字符缓冲区 用变量传递参数用变量传递参数.386.386.model flat , stdcall.model flat , stdcallinclude masm32includeio32.incinclude masm32includeio32.inc.stack.stack.data.datacount equ 10count equ 10; ;数组元素个数数组元素个数array dword 1,2,3,
50、4,5,6,7,8,9,10;array dword 1,2,3,4,5,6,7,8,9,10;数组数组result dword ?result dword ?; ;校验和校验和Hexstr byte 8 dup(?),0Hexstr byte 8 dup(?),0; ;存放转换字符串缓冲区,以存放转换字符串缓冲区,以0 0结尾结尾例例7-10 .code.codestart:start:; ;设置入口参数设置入口参数mov ebx,offset array;EBXmov ebx,offset array;EBX数组的偏移地址数组的偏移地址mov ecx,count ;ECXmov ecx,c
51、ount ;ECX数组的元素个数数组的元素个数call checksum ;call checksum ;调用求和过程调用求和过程mov result,eax ;mov result,eax ;处理出口参数处理出口参数; ;显示校验和显示校验和call eaxsavecall eaxsave; ;将将3232位数据转换为十六进制字符串位数据转换为十六进制字符串WriteString Hexstr ;WriteString Hexstr ;显示转换结果显示转换结果retret例例7-10 ; ;计算校验和计算校验和; ;入口参数:入口参数:EBX=EBX=数组偏移地址,数组偏移地址,ECX=EC
52、X=元素个数元素个数; ;出口参数:出口参数:EAX=EAX=校验和校验和; ;说明:除说明:除EAX/EBX/ECXEAX/EBX/ECX外,不影响其他寄存器外,不影响其他寄存器 checksumchecksumprocproc xor eax,eaxxor eax,eax; ;累加器清累加器清0 0 suma:add eax,ebxsuma:add eax,ebx; ;求和求和add ebx,4add ebx,4; ;指向下一个数据指向下一个数据loop sumaloop sumaretret checksumchecksumendpendp例例7-10 ; ;将将3232位数据转换为十六
53、进制字符串位数据转换为十六进制字符串; ;入口参数:入口参数:result=result=要显示的要显示的3232位数据,位数据,;HexStr=;HexStr=字符缓冲区字符缓冲区eaxsave proceaxsave procmov eax, resultmov eax, resultmov edi, offset HexStr mov edi, offset HexStr ;edi=HexStr;edi=HexStr的首地址的首地址mov ecx, 4mov ecx, 4eaxsave1: rol eax, 8;eaxsave1: rol eax, 8;从高位开始转换从高位开始转换pus
54、h eaxpush eax ; ;暂存暂存axax例例7-10 mov dl,al ;mov dl,al ;转换转换alal的高的高4 4位位shr dl,4shr dl,4or dl,30h ;alor dl,30h ;al高高4 4位变成位变成3 3cmp dl,39hcmp dl,39hjbe alsave1jbe alsave1add dl,7;add dl,7;是是0Ah0Fh0Ah0Fh,其,其ASCIIASCII码还要加上码还要加上7 7alsave1: mov edi,dlalsave1: mov edi,dl; ;保存高四位保存高四位pop edxpop edx ; ;恢复原
55、恢复原axax值到值到dxdxand dl,0fh ;and dl,0fh ;转换转换alal的低的低4 4位位or dl,30hor dl,30h例例7-10 cmp dl,39hcmp dl,39hjbe alsave2jbe alsave2add dl,7add dl,7alsave2: mov edi+1, dlalsave2: mov edi+1, dl ; ;保存低四位保存低四位add edi,2 ;add edi,2 ;修改存放字符串的地址指针修改存放字符串的地址指针loop eaxsave1loop eaxsave1; ;调用程序段结束调用程序段结束retreteaxsave
56、endpeaxsave endpend startend start例例7-10 主程序将子程序的入口参数压入堆栈,主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序子程序将出口参数压入堆栈,主程序弹出堆栈取得它们弹出堆栈取得它们入口参数:入口参数:顺序压入偏移地址和元素个数顺序压入偏移地址和元素个数出口参数:出口参数:EAX校验和校验和用堆栈传递参数用堆栈传递参数 要注意堆栈的分配情况,保证参数存取正要注意堆栈的分配情况,保证参数存取正确、子程序正确返回,并保持堆栈平衡确、子程序正确返回,并保持堆栈平衡.386.386.model
57、flat , stdcall.model flat , stdcallinclude masm32includeio32.incinclude masm32includeio32.inc.stack.stack.data.datacount equ 10count equ 10; ;数组元素个数数组元素个数array dword 1,2,3,4,5,6,7,8,9,10;array dword 1,2,3,4,5,6,7,8,9,10;数组数组result dword ?result dword ?; ;校验和校验和Hexstr byte 8 dup(?),0Hexstr byte 8 dup
58、(?),0; ;增加存放转换字符串缓冲区,以增加存放转换字符串缓冲区,以0 0结尾结尾例例7-11 .code.codestart:start:mov eax,offset arraymov eax,offset array ; ;设置入口参数设置入口参数push eaxpush eax ; ;压入数组的偏移地址压入数组的偏移地址mov eax,countmov eax,countpush eaxpush eax ; ;压入数组的元素个数压入数组的元素个数call checksumccall checksumc; ;调用求和过程调用求和过程add esp,8add esp,8 ; ;主程序平衡
59、堆栈主程序平衡堆栈mov result,eaxmov result,eax; ;保存校验和保存校验和WriteDecDword eax ;WriteDecDword eax ;显示转换结果显示转换结果 retret例例7-11 ; ;计算校验和的过程计算校验和的过程; ;入口参数:在堆栈压入数组的偏移地址和入口参数:在堆栈压入数组的偏移地址和元素个数元素个数; ;出口参数:出口参数:eax=eax=校验和校验和checksumc procchecksumc procpush ebppush ebpmov ebp,esp ;EBPmov ebp,esp ;EBP指向当前栈顶,指向当前栈顶,pus
60、h ebxpush ebx ; ;保护使用的保护使用的bxbx和和cxcx寄存器寄存器push ecxpush ecx例例7-11 mov ebx,ebp+12mov ebx,ebp+12;EBXSS:EBP+12;EBXSS:EBP+12(数组的偏移地址)(数组的偏移地址)mov ecx,ebp+8mov ecx,ebp+8;ECXSS:EBP+8;ECXSS:EBP+8(数组的元素个数)(数组的元素个数)xor eax,eaxxor eax,eax; ;累加器清累加器清0 0sumc: add eax,ebxsumc: add eax,ebx例例7-11 ; ;求和:求和:EAXEAX+D
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论