版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、VI. 堆栈、子过程,使用堆栈 子程序 子程序定义 调用与返回 Win32 API 堆栈与参数传递、自动变量,使用堆栈,堆栈 从概念上,堆栈是一种先进后出(FILO)的队列结构 新进栈的数据总是位于栈的顶部 栈顶的数据最先出栈,运行时栈(Runtime Stack) 在程序内存空间中保留的一段连续的内存区域; CPU硬件电路直接支持堆栈机构 - 使用两个寄存器实现运行时栈的自动操作:堆栈段寄存器-SS,堆栈指针-ESP 在32位汇编的情况下,SS的内容由系统管理,不要在程序中对它进行改动;但在程序中可能需要处理堆栈指针ESP,对32位汇编程序,运行时栈由系统自动建立,程序无须考虑堆栈建立问题。
2、在程序入口,运行时栈已经就绪。,堆栈指令 push reg16 / mem16 push reg32 / mem32 push imm32 pop reg16 / mem16 pop reg32 / mem32,32位汇编程序中(使用伪指令.386及以上时),指令中的立即数总是32位,指令执行后堆栈的状态: 堆栈指针所指的位置 ? 栈顶的数据 ?,. . ; .stack 4096 . . .code start: mov eax, 0 mov ax, 0C06h,系统在栈上已存放用于启动、退出程序的重要信息;,ESP,地址增长,ESP指向栈顶;,0C06,. . ; .stack 4096
3、. . .code start: mov eax, 0 mov ax, 0C06h push ax,ESP,0C06H进栈 堆栈增长 - ESP递减,地址增长,0C06,. . ; .stack 4096 . . .code start: mov eax, 0 mov ax, 0C06h push ax push 0110 0C06h,ESP,0110 0C06,地址增长,0C06H进栈 堆栈增长 - ESP递减,0C06,. . ; .stack 4096 . . .code start: mov eax, 0 mov ax, 0C06h push ax push 0110 0C06h po
4、p edx,ESP,0110 0C06,4字节出栈(到EDX) 堆栈回卷 - ESP递增,地址增长,运行时栈工作过程,0C06,. . ; .stack 4096 . . .code start: mov eax, 0 mov ax, 0C06h push ax push 0110 0C06h pop edx pop bx,ESP,0110 0C06,存储单元被系统回收 对程序而言,不再可用,地址增长,2字节出栈(到BX) 堆栈回卷 - ESP递增,例: 字符串反序存储,. . greeting byte “Welcome to school!” . .,将字符串greeting的字符顺序反转
5、,?,W,例: 字符串反序存储,. . greeting byte “Welcome to school!” . .,将字符串greeting的字符顺序反转,?,mov esi, 0 movzx ax, greeting esi push ax ; push on stack inc esi,mov esi, 0 pop ax mov greeting esi, al inc esi,W,子程序,子程序(子过程,Procedure) 一段可通用的代码,实现在程序中须多次使用的某种功能。,例:将二进制无符号WORD整数转换为适合日常阅读的形式?,16位无符号整数取值范围:0 -216-1 = 6
6、5535,16位无符号整数转换为字符串。,结果字符串长度:6字节,定义子程序(伪指令PROC、ENDP),. . . . mov eax, 0 ; 子程序体 . .,其他代码,如其他子过程,1).过程名:,实现子过程功能的指令块,子程序名 PROC 子程序名 ENDP,子过程第一条指令的内存地址,输入需处理的数据?,输出处理结果?,; int Add2Int (int x, int y) ; x ebx ; y edx ; eax sum ; Add2Int PROC Add2Int ENDP,约定通过寄存器向子过程传递参数,mov eax, ebx add eax, edx ret,ret指
7、令 :从子程序返回,一般通过EAX传递向调用方传递返回值,ret指令,子程序调用和返回 调用方使用CALL指令调用子程序: 调用子程序前,首先按照约定将需要传递给子程序的数据存放在指定位置 子程序中使用RET指令返回,. . call Add2Int,. . mov ebx, 5 mov edx, 6 call Add2Int L1: mov sum, eax . . ; x ebx , y edx ; eax sum Add2Int PROC mov eax, ebx . . ret Add2Int ENDP,Add2Int (5, 6),. . mov ebx, 5 mov edx, 6
8、call Add2Int L1: mov sum, eax . . ; x ebx , y edx ; eax sum Add2Int PROC mov eax, ebx . . ret Add2Int ENDP,Add2Int (5, 6),ESP,EIP,Add2Int (5, 6),ESP,EIP,L1,call 指令首先将返回地址压栈; 再转到子程序入口;,. . mov ebx, 5 mov edx, 6 call Add2Int L1: mov sum, eax . . ; x ebx , y edx ; eax sum Add2Int PROC mov eax, ebx . .
9、ret Add2Int ENDP,Add2Int (5, 6),ESP,EIP,L1,L1,. . mov ebx, 5 mov edx, 6 call Add2Int L1: mov sum, eax . . ; x ebx , y edx ; eax sum Add2Int PROC mov eax, ebx . . ret Add2Int ENDP,Add2Int (5, 6),ESP,EIP,L1,L1,ret 指令将当前栈顶的内容弹入EIP; EIP指向CALL的下一条指令;,ret指令能正确返回的条件?,. . mov ebx, 5 mov edx, 6 call Add2Int
10、L1: mov sum, eax . . ; x ebx , y edx ; eax sum Add2Int PROC mov eax, ebx . . ret Add2Int ENDP,; int Add2Int (int x, int y) ; x ebx ; y edx ; eax sum ; Add2Int PROC mov eax, ebx add eax, edx ret Add2Int ENDP,. . ; Add2Int ( 5, 6 ) ; mov ebx, 5 mov edx, 6 call Add2Int L1: inc eax . .,返回地址L1被压入栈顶,栈顶内容弹
11、进EIP,针对每个子程序,约定参数、返回值的传递。,栈顶内容是否为返回地址L1 ?,确保正确返回,; int Add2Int (int x, int y) ; x ebx ; y edx ; eax sum ; Add2Int PROC push 0400 00E8h mov eax, ebx add eax, edx pop ebx ret Add2Int ENDP,. . ; Add2Int ( 5, 6 ) ; mov ebx, 5 mov edx, 6 call Add2Int L1: inc eax . .,确保正确返回,(1)保证执行RET时,栈顶为返回地址L1,如果子程序中改变了
12、堆栈状态?,返回哪里?,; int Add2Int (int x, int y) ; x ebx ; y edx ; eax sum ; Add2Int PROC . . push ecx mov ecx, 0 . . pop ecx ret Add2Int ENDP,. . ; Add2Int ( 5, 6 ) ; mov ebx, 5 mov edx, 6 call Add2Int L1: inc eax . .,确保正确返回,(2)子程序执行后,除约定的返回值寄存器外,其他寄存器的内容不应受到影响,执行ret 指令时; 返回地址位于栈顶; 使用过的非约定寄存器恢复原状,ECX = 5,E
13、CX = 0 ?,备份寄存器,恢复寄存器,伪指令USES,子程序名 PROC ; 子程序体 ret 子程序名 ENDP,子程序中使用寄存器r1、r2,子程序名 PROC USES r1, r2 ; 子程序体 ret 子程序名 ENDP,push r1 push r2,pop r2 pop r1,汇编器自动生成寄存器备份、恢复指令,其他堆栈指令 pushad EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI 依次压栈。 popad 与pushad对应 pusha、popa 16位寄存器依次压栈/出栈,(push All Dword),子过程中,寄存器备份与恢复,例:将小写字符串转换
14、为大写,. . .data s1 BYTE word, 0 s2 BYTE asm, 0 s3 BYTE windows, 0 . .,; void capital(char* p, int n) ; pstr = ebx ; len = eax upper PROC upper ENDP,mov ebx, OFFSET s2 mov eax, SIZEOF s2 - 1 call upper . .,upper. asm,caller. asm,mov ecx, eax mov esi, ebx L1: sub BYTE PTR esi, 20h inc esi loop L1 ret,US
15、ES ECX, ESI,c:masm615ml /Cp /c /coff /Zi /Fl caller.asm upper.asm C:masm615link32 /DEBUG /MAP /SUBSYSTEM:WINDOWS /LIBPATH:C:masm615lib caller.obj upper.obj kernel32.lib user32.lib gdi32.lib,Win32汇编程序模板,. . .data . . .code start: INVOKE ExitProcess, 0 END start,. . .data . . .code func1 PROC . . func
16、1 ENDP . . MyFunc PROC call func1 . . INVOKE ExitProcess, 0 MyFunc ENDP END MyFunc,程序由子过程构成 伪指令END指定程序入口,设计子程序,将WORD(无符号整数)转换为适合阅读的10进制形式?,Tbl BYTE “0123456789”,16位无符号整数转换为字符串。,. . .data val WORD 35087 . .,vstr BYTE 6 dup (0),数值3 字符 3,数值5 字符 5,Val/10000 = 3,Tbl3 = 3,Win32 API,使用汇编可以通过调用Win32 API,开发W
17、indows应用程序。 Win32 API由Kernel32.lib、User32.lib、GDI32.lib导出,原型可以通过头文件Windows.h查找。 汇编中调用Win32 API,.MODEL伪指令必须指定stdcall,并用PROTO说明API原型,之后程序可以用INVOKE调用已说明的API,例:消息框,int WINAPI MessageBoxA( HWND hWnd , /窗口句柄,可以为0 LPCSTR lpMsg, /提示信息 LPCSTR lpCaption, /消息框标题 UINT uType); /消息框类型,. . MessageBoxA PROTO, hWin
18、: PTR, strMsg : PTR BYTE, strCap : PTR BYTE, utype : DWORD . .,PROTO申明中使用伪指令PTR说明指针参数的属性,例:消息框,. . strCap BYTE A MessageBox! , 0 strMsg BYTE Hey, it works!, 0 . . mov eax, 0 ; utype: 2, 4 INVOKE MessageBoxA, 0, ADDR strMsg, ADDR strCap, eax . .,INVOKE指令中传递的参数可以为表达式、寄存器、带操作符ADDR的地址表达式,. . MessageBoxA
19、 PROTO, hWin : PTR, strMsg : PTR BYTE, strCap : PTR BYTE, utype : DWORD . .,PROTO申明中使用伪指令PTR说明指针参数的属性,堆栈与参数传递,堆栈参数传递 调用者将参数按约定的顺序压入运行时堆栈 调用子程序 子程序从堆栈获得参数 子程序处理数据 从子程序中返回,参数进栈顺序约定以后,同一机制适用于所有子程序,参数进栈,6,. . push 6 . . Add2Int PROC ret Add2Int ENDP,EIP,ESP,Add2Int (5, 6);,参数进栈,6,. . push 6 push 5 . . A
20、dd2Int PROC ret Add2Int ENDP,Add2Int (5, 6);,EIP,ESP,5,L1,调用子过程,6,5,. . push 6 push 5 call Add2Int L1 : inc eax . . Add2Int PROC ret Add2Int ENDP,Add2Int (5, 6);,EIP,ESP,L1,调用子过程,6,5,. . push 6 push 5 call Add2Int L1 : inc eax . . Add2Int PROC ret Add2Int ENDP,L1,堆栈状态:返回地址:栈顶 参数表 :随后,call指令使L1压入当前栈顶
21、,EIP,ESP,获取参数,L1,6,5,. . push 6 push 5 call Add2Int L1 : inc eax . . Add2Int PROC mov eax, esp+4 ; 5 add eax, esp+8 ; 6 ret Add2Int ENDP,EIP,ESP,EIP,返回,L1,6,5,. . push 6 push 5 call Add2Int L1 : inc eax . . Add2Int PROC mov eax, esp+4 ; 5 add eax, esp+8 ; 6 ret Add2Int ENDP,L1,ESP,ret指令将当前栈顶内容弹入EIP,
22、Add2Int( 5, 6 ),参数从右至左入栈,EIP,堆栈清理,6,5,. . push 6 push 5 call Add2Int L1 : inc eax . . push 8 push 7 call Add2Int L2 : inc eax,ESP,Add2Int( 5, 6 ),参数从右至左入栈,Add2Int( 7, 8 ),8,7,L2,随着子程序调用次数增加,堆栈增长!,调用返回,第一次调用,堆栈清理,. . push 6 push 5 call Add2Int add esp, 8 L1 : inc eax,子过程调用返回后,堆栈应恢复到第一个参数压栈前的状态,6,5,清理
23、栈上的参数,EIP,ESP,Add2Int( 5, 6 ),参数从右至左入栈,按从右至左的顺序将参数压栈,call指令将返回地址压入栈顶,转向子程序。 清理堆栈,保证堆栈恢复为第一个参数压栈前的状态。,从堆栈中读取参数。 返回前保证堆栈指针恢复为入口时的状态,即保证返回地址位于栈顶 。 ret指令将返回地址从栈顶弹入EIP寄存器,返回调用方 。,C调用约定,Add2Int( 5, 6 ),伪指令INVOKE,PROTO,从堆栈中读取参数。 返回前保证堆栈指针恢复为入口时的状态,即保证返回地址位于栈顶 。 ret指令将返回地址从栈顶弹入EIP寄存器,返回调用方 。,. . ; int Add2I
24、nt (int a , int b) ; Add2Int PROC C , ret Add2Int ENDP . .,Add2Int( 5, 6 ),参数自右至左进栈;,a : DWORD, b : DWORD,mov eax, a ; a : esp+4 add eax, b ; b : esp+8,声明参数列表,汇编器可以自动计算参数地址;,参数可直接寻址,伪指令INVOKE,PROTO,C调用约定,. . ; int Add2Int (int a , int b) ; Add2Int PROC C , ret Add2Int ENDP . .,Add2Int( 5, 6 ),参数自右至左
25、进栈;,a : DWORD, b : DWORD,mov eax, a ; a : esp+4 add eax, b ; b : esp+8,声明参数列表,汇编器可以自动计算参数地址;,参数可直接寻址,. . .data X DWORD ? Y DWORD ? ; Add2Int(X, Y),Add2Int PROTO C, a : DWORD, b : DWORD,.code . . INVOKE Add2Int , X, Y . .,汇编器自动生成参数传递和堆栈清理指令,伪指令LOCAL,. . ; int Add2Int (int a , int b) ; Add2Int PROC C
26、, ret Add2Int ENDP,Add2Int( 5, 6 ),a : DWORD, b : DWORD,mov eax, a ; a : esp+4 add eax, b ; b : esp+8,. . .data X DWORD ? Y DWORD ? ; Add2Int(X, Y),Add2Int PROTO C, a : DWORD, b : DWORD,.code . . INVOKE Add2Int , X, Y . .,LOCAL t1:DWORD, t2: DWORD,-在堆栈空间中分配局部变量,mov t1, ecx,mov t2, eax,汇编器自动生成在堆栈上分配相
27、应存储单元的指令,直接寻址访问,例:计算方差,对a、b : V= (a - M)2+(b-M)2 计算M: M = (a + b)/2 2. 计算 Qa : Qa = (a - M) 2 3. 计算Qb : Qb = (b - M)2 4. 计算V: V = Qa + Qb,int variance (int x , int y) int M, Qa, Qb; M = (x + y)/2; Qa = (x M)2; Qb = (y M)2; return Qa + Qb;,int variance (int x , int y) int M, Qa, Qb; M = (x + y)/2; Qa
28、 = (x M)2; Qb = (y M)2; return Qa + Qb;,; int variance (int x , int y) variance PROC C , ret variance ENDP,x : DWORD, y : DWORD,LOCAL M:DWORD, Qa: DWORD, Qb:DWORD,mov eax, x ; x add eax, y ; +y shr eax, 1 mov M, eax ; M,. . ; Qa, Qb mov eax, Qa ; Qa add eax, Qb ; +Qb mov ebx, 0cdcdcdcdh,例:计算方差,USES
29、EBX,例:计算方差,; int variance (int x , int y) variance PROC C , ret variance ENDP,x : DWORD, y : DWORD,LOCAL M:DWORD, Qa: DWORD, Qb:DWORD,mov eax, x ; x add eax, y ; +y shr eax, 1 mov M, eax ; M,.data a DWORD ? b DWORD ? ;,variance PROTO C, x : DWORD, y : DWORD,.code . . INVOKE variance, a, b . .,参数、局部变
30、量可以直接寻址,参数进栈; 堆栈清理,声明为C函数,声明局部变量,声明按C规范调用,. . ; Qa, Qb mov eax, Qa ; Qa add eax, Qb ; +Qb mov ebx, 0cdcdcdcdh,USES EBX,例:计算方差,; int variance (int x , int y) variance PROC C USES EBX , ret variance ENDP,x : DWORD, y : DWORD,LOCAL M:DWORD, Qa: DWORD, Qb:DWORD,mov eax, x ; x add eax, y ; +y shr eax, 1
31、mov M, eax ; M,int variance(int a, int b);,. . int a = 100, b = 200; int var; . . var = variance(a, b); . .,可以在C程序中直接被调用,. . ; Qa, Qb mov eax, Qa ; Qa add eax, Qb ; +Qb mov ebx, 0cdcdcdcdh,参数、局部变量可以直接寻址,例:数组(升序)排序,5,-2,依次两两比较,如果前一元素大于后一元素,交换,例:数组(升序)排序,-2,5,依次两两比较,如果前一元素大于后一元素,交换,例:数组(升序)排序,-2,0,依次两
32、两比较,如果前一元素大于后一元素,交换,例:数组(升序)排序,-2,0,对剩下的数,重复上述过程,重复上述过程,没有发生交换,排序结束,数组中最大的数排到最后,. . .data . . wlist SWORD 3, 5, -2, 0, 1 . .,例:数组(升序)排序,对剩下的数,重复上述过程,数组中最大的数排到最后,设计子过程完成,max2last PROC C , ret max2last ENDP,cnt : WORD LOCAL xchged : WORD mov xchged, 0 mov ax, xchged,edi,edi+2,. . .data . . wlist SWORD 3, 5, -2, 0, 1 . .,例:数组(升序)排序,对剩下的数,重复上述过程,数组中最大的数排到最后,设计子过程完成,max2last PROC C , ret max2last ENDP,cnt : WORD LOCAL xchged : WOR
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 陕西省渭南市2026年高三第五次模拟考试语文试卷含解析
- 2026浙大宁波理工学院招聘派遣制工作人员1人笔试参考题库及答案解析
- 2026年浑源县教师招聘考试备考题库及答案解析
- 2026年平遥县教师招聘考试备考试题及答案解析
- 2026年和县教师招聘笔试参考题库及答案解析
- 国家开发银行青海分行2027届校园招聘笔试备考试题及答案解析
- 2026武汉东湖高新区左岭街社区卫生服务中心招聘劳务派遣工作人员41人考试模拟试题及答案解析
- 2026年大竹县教师招聘笔试备考题库及答案解析
- 乐山高新区嘉祥外国语学校招聘 (46人)笔试备考题库及答案解析
- 2027年度中国石化毕业生招聘考试参考题库及答案解析
- 金融管理综合应用案例昌盛餐厅
- 2027届广州市天河区普通高中毕业班适应性训练作文题目解析及范文:长期规划是对未来的研判与谋划
- 长春初中语文九上《短文两篇-孔子世家赞》
- 道路维修验收标准方案
- 鱼类育种课件
- 《JBT 7257-2018 行车式提板刮渣刮砂机》(2026年)实施指南
- 福建省泉州市永春第一中学2025-2026学年高二上学期开学考试数学试卷
- 嗜酸性肉芽肿性多血管炎诊治多学科专家共识(2025年版)解读
- 甲亢的中医护理方案
- 八年级物理第一次月考卷(全解全析)(北京地区人教版)
- 2024年新人教版七年级上册数学教学课件 第四章 整式的加减 数学活动
评论
0/150
提交评论