5.4 堆栈操作
5.4.2 POP和PUSH指令
PUSHFD 指令把 32 位 EFLAGS 寄存器内容压入堆栈,而 POPFD 指令则把栈顶单元内容弹出到 EFLAGS 寄存器:
PUSHAD 指令按照 EAX、ECX、EDX、EBX、ESP(执行 PUSHAD 之前的值)、EBP、ESI 和 EDI 的顺序,将所有 32 位通用寄存器压入堆栈。
POPAD 指令按照相反顺序将同样的寄存器弹出堆栈。与之相似,PUSHA 指令按序(AX、CX、DX、BX、SP、BP、SI 和 DI)将 16 位通用寄存器压入堆栈。
POPA 指令按照相反顺序将同样的寄存器弹出堆栈。在 16 位模式下,只能使用 PUSHA 和 POPA 指令。
5.8 编程练习
1.绘制彩色文本
TITLE test project INCLUDE Irvine32.inc .data buffer BYTE 'Hk_Mayfly',13,10,0 color DWORD 1,2,3,4,6 .code main PROC mov esi,OFFSET color mov edx,OFFSET buffer mov ecx,4 S: mov eax,[esi] shl eax,4 add eax,[esi+TYPE color] call SetTextColor call WriteString add esi,TYPE color loop S call WaitMsg exit main ENDP END main
2.斐波那契数文件
TITLE test project INCLUDE Irvine32.inc BUF_SIZE=47 .data filename BYTE 'Fib.txt',0 fileHandle DWORD ?;文件句柄 Num DWORD BUF_SIZE dup(0) .code main PROC ;句柄与文件建立关系 mov edx,OFFSET filename call CreateOutputFile mov fileHandle,eax mov esi,0 mov [Num],1 mov [Num+TYPE Num],1 mov ecx,45 ;循环计算第3~47个斐波那契数 S: mov eax,[Num+esi] add eax,[Num+TYPE Num+esi] add esi,TYPE Num mov [Num+TYPE Num+esi],eax loop S ;将Num中的数据写入文件 mov eax,fileHandle mov edx,OFFSET Num mov ecx,SIZE Num call WriteToFile ;将Num中的数据显示到终端 mov esi,OFFSET Num mov ecx,LENGTHOF Num mov ebx,TYPE Num call DumpMem call WaitMsg exit main ENDP END main
3.简单加法(1)
TITLE test project INCLUDE Irvine32.inc Str1 EQU <'Please input two num:',13,10,0> .data Str2 BYTE Str1 .code main PROC ;清屏 call ClrScr ;定位光标 mov dh,12 mov dl,39 call Gotoxy ;输出提示字符串 mov edx,OFFSET Str2 call WriteString ;读取第一个数,保存到ebx call ReadInt mov ebx,eax call ReadInt ;读取第二个数,并与第一个数相加,得到和,在屏幕显示 add eax,ebx call WriteInt call WaitMsg exit main ENDP END main
4.简单加法(2)
TITLE test project INCLUDE Irvine32.inc Str1 EQU <'Please input two num:',13,10,0> .data Str2 BYTE Str1 .code main PROC mov ecx,3 S: ;清屏 call ClrScr ;定位光标 mov dh,12 mov dl,39 call Gotoxy ;输出提示字符串 mov edx,OFFSET Str2 call WriteString ;读取第一个数,保存到ebx call ReadInt mov ebx,eax call ReadInt ;读取第二个数,并与第一个数相加,得到和,在屏幕显示 add eax,ebx call WriteInt call WaitMsg loop S call WaitMsg exit main ENDP END main
5.随机整数
TITLE test project INCLUDE Irvine32.inc .data randVal DWORD 50 dup(?) .code main PROC mov ecx,50 mov esi,0 S: mov eax,41 call RandomRange mov [randVal+esi],eax sub [randVal+esi],20 add esi,TYPE randVal loop S mov esi,OFFSET randVal mov ecx,LENGTHOF randVal mov ebx,TYPE randVal call DumpMem call WaitMsg exit main ENDP END main
6.随机字符串
TITLE test project INCLUDE Irvine32.inc .data randVal BYTE 13 dup(0) .code main PROC mov ecx,20 S: push ecx mov esi,0 mov ecx,10 S2: mov eax,26 call RandomRange mov [randVal+esi],al add [randVal+esi],65 add esi,1 loop S2 mov [randVal+esi],10 add esi,1 mov [randVal+esi],13 add esi,1 mov [randVal+esi],0 mov edx,OFFSET randVal call WriteString pop ecx loop S mov esi,OFFSET randVal mov ecx,LENGTHOF randVal mov ebx,1 call DumpMem call WaitMsg exit main ENDP END main
7.随机屏幕位置
TITLE test project INCLUDE Irvine32.inc .code main PROC mov ecx,100 S: mov eax,0 call GetMaxXY;返回值在dx中,dh存行,dl存列 mov al,dl call RandomRange;从eax中传入,返回值存储在eax中 mov dl,al mov al,dh call RandomRange mov dh,al call Gotoxy;从dx中传入 mov al,'A' call WriteChar mov eax,100 call Delay loop S call WaitMsg exit main ENDP END main
8.色彩矩阵
TITLE test project INCLUDE Irvine32.inc .data Str1 BYTE 'CTF{It_is_easy}',13,10,0 .code main PROC mov eax,0 mov esi,0 mov ecx,15 S: push ecx mov ecx,15 S1: shl esi,4 add eax,esi call setTextColor mov edx,OFFSET Str1 call WriteString inc esi loop S1 pop ecx inc eax loop S call WaitMsg exit main ENDP END main
9.求和程序
TITLE test project INCLUDE Irvine32.inc ARRAY_SIZE = 20 .data Info BYTE 'How many integers will be added?',13,10,0 Info1 BYTE "The array cannot be large than",0 LineFeed BYTE 13,10,0 .code main PROC ;输入数组大小 mov edx,OFFSET Info call WriteString call ReadInt ;比较是否越界 cmp eax,ARRAY_SIZE jbe success ;越界输出 mov edx,OFFSET Info1 call WriteString mov eax,ARRAY_SIZE call WriteInt mov edx,OFFSET LineFeed call WriteString success: call WaitMsg exit main ENDP END main