WriteWindowsMsg - Displays most recent error message generated by MS-Windows
Example 1
.data fileName BYTE 80 DUP(0) nameCount DWORD ? .code mov edx,OFFSET fileName mov ecx,SIZEOF fileName – 1 call ReadString mov nameCount, eax
Example 2 反转字符串
TITLE Reversing a String INCLUDE Irvine32.inc .data aName BYTE “Abranham Lincoln”,0 nameSize=($-aName)-1 .code
main PROC move cx, nameSize mov esi,0
L1: movzx eax, aName[esi] push eax inc esi loop L1 mov ecx, nameSize mov esi, 0 L2: pop eax mov aName[esi], al inc esi loop L2 move dx,OFFSET aName call WriteString call Crlf exit main ENDP
17
END main
三.堆栈操作
运行时栈是由 cpu 直接管理的内存数组,它使用两个寄存器:SS 和 ESP。
在保护模式下 SS 寄存器存放的是段选择子,用户模式程序不应对其进行修改。ESP 寄存器
存放的是指向特定位置的一个32位偏移地址。很少需要直接操纵 ESP的值,通常是由CALL,RET,PUSH 和 POP 等指令间接修改的。保护模式下,每个堆栈位置包含 32 个数据位。实地址模式下,每个堆栈位置包含 16 个数据位。
规则:从顶部出栈,从顶部压栈,后进先出 LIFO 1. PUSH 操作
首先将堆栈指针减 4 (32bits),然后把要压栈的值复制到堆栈指针所指的位置处。堆栈向下增长。
2. POP 操作
首先从堆栈顶端移走一个值并将其复制到寄存器或内存变量中,在值从栈顶弹出之后,堆栈指针相应增加,并指向栈中与弹出数据相邻的高位置。
18
3. 堆栈的应用:
a.用作寄存器值的临时保存区域,在寄存器使用完毕后,通过堆栈恢复原始值。
b.CALL 指令执行时,CPU 用堆栈保存当前被调用过程的返回地址。 c. 调用过程时,通过堆栈传递参数。
d.过程内的局域变量在堆栈上创建,过程结束后,变量被丢弃。 4. 指令格式:
PUSH r/m16
PUSH r/m32 PUSH imm32
POP r/m16 POP r/m32 5. PUSHFD 和 POPFD
对 EFLAGS 寄存器的值进行压栈和出栈。(MOV 指令不能复制标志寄存器的值至变量或寄存器中,因此使用 PUSHFD 指令可以保存标志寄存器)。使用指令时,要保障程序执行罗京不会跳过 POPFD 指令。
6. PUSHAD 和 POPAD
PUSHAD 指令在堆栈上按顺序压入所有 32 位通用寄存器的值:EAX ECX EDX EBX ESP POPAD 指令以相反顺序从堆栈中弹出这些通用寄存器。
PUSHA 和 POPA 对 16 位寄存器做相同操作(AX CX DX BX SP)。
7. 嵌套循环
当使用嵌套循环时,在进入内部循环时将外部循环的计数器压栈(ecx)
19
四.过程的定义和使用
1. CALL 和 RET 指令
CALL 指令把返回地址压入堆栈并把被调用过程的地址复制到指令指针寄存器中。在新的内存地址执行指令,以实现对过程的调用。
RET 指令从堆栈中弹出返回地址并送到指令寄存器中,使处理器返回到程序中过程被调用的地方继续执行。
32 位模式下,CPU 总是执行 EIP 寄存器所指向的内存地址处得指令(16 位->IP 寄存器)
2. 传递参数 Example 求数组和
ArraySum PROC
; Receives: ESI points to an array of doublewords, ; ECX = number of array elements. ; Returns: EAX = sum
20
相关推荐: