重点难点内容
- 掌握堆栈指令
-
- 指令:
push、pop、CALL、RET、PROC、ENDP 和 USES。 - 应用:理解堆栈操作的原理,包括入栈和出栈操作,以及堆栈在程序中的作用。
堆栈操作
1. 堆栈概念
- 定义:堆栈是内存中的一部分区域,用于存储数据,遵循先进后出(LIFO)的原则。
- 寄存器:
-
- ESP(32位寄存器)用于指示堆栈顶部的地址。
- SP(16位寄存器)在16位模式下使用。
- 堆栈的地址从高地址向低地址增长。
2. 入栈与出栈操作
-
-
PUSH reg/mem16、PUSH reg/mem32、PUSH imm32。- 特殊指令:
pushfd(将标志寄存器压入堆栈)、pushad(将所有32位通用寄存器压入堆栈)、pusha(将所有16位通用寄存器压入堆栈)。
push eax ; 将EAX寄存器值压入堆栈
push 10h ; 将立即数10h压入堆栈
pushfd ; 将标志寄存器(EFLAGS)压入堆栈
-
-
POP reg/mem16、POP reg/mem32。- 特殊指令:
popfd(将堆栈中的内容弹出到标志寄存器)、popad(按顺序弹出所有32位通用寄存器)、popa(按顺序弹出所有16位通用寄存器)。
pop eax ; 将堆栈顶的值弹出到EAX寄存器
popfd ; 将堆栈顶的标志寄存器值弹出
过程(子程序、函数)
1. 定义与调用
main PROC
; 主程序代码
main ENDP
main PROC
call sample ; 调用子程序sample
main ENDP
- 返回指令:
RET指令从子程序返回,恢复主程序的执行流。
sample PROC
; 子程序代码
ret ; 返回主程序
sample ENDP
2. 嵌套调用
- 示例:过程可以嵌套调用,即在一个过程内部调用另一个过程。
call Sub1
Sub1 PROC
call Sub2
Sub2 PROC
call Sub3
Sub2 ENDP
Sub1 ENDP
3. 参数传递
mov eax, 10000h ; 参数1
mov ebx, 20000h ; 参数2
mov ecx, 30000h ; 参数3
call Sumof ; 调用子程序
.data
array DWORD 10000h, 20000h, 30000h, 40000h, 50000h
theSum DWORD
.code
main PROC
mov esi, OFFSET array ; ESI指向数组
mov ecx, LENGTHOF array ; ECX为数组计数器
call ArraySum ; 计算和数
mov theSum, eax ; 将结果存储在theSum
4. 使用push和pop保存与恢复寄存器
- 保存和恢复寄存器:使用
push和pop指令保存和恢复在调用过程中被修改的寄存器值。
ArraySum PROC USES esi ecx
mov eax, 0
L1:
add eax, [esi] ; 累加数组元素
add esi, TYPE DWORD ; 指向下一个数组元素
loop L1 ; 循环遍历数组
ret ; 返回
ArraySum ENDP
链接到外部库
1. 链接库概念
- 定义:链接库包含已汇编为机器代码的过程(子程序)。通过链接库,可以重用其他程序中定义的过程和函数。
2. Irvine32链接库
- 概念:Irvine32链接库是专为初学者设计的,提供简单的输入输出接口和一些常用的过程。常见的过程包括:
-
WriteInt:将整数输出到控制台。WriteString:向控制台输出字符串。WriteChar:输出一个字符。Crlf:在控制台窗口写行结束符
总结
- 堆栈操作:通过
push和pop指令实现数据入栈和出栈,堆栈用于存储返回地址、局部变量和保存寄存器状态等。 - 过程定义与调用:使用
PROC和ENDP定义过程,使用CALL指令调用,RET指令返回。 - 参数传递:可以通过寄存器、指针和计数器传递参数,子程序可以保存和恢复寄存器的状态,避免修改主程序的寄存器值。
- 外部库链接:通过使用Irvine32链接库,可以调用常见的输入输出和控制过程,简化程序开发。