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

第五章 过程_屏幕显示_02第五章 过程_屏幕显示_03

 

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

第五章 过程_数据_04

 

 

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

第五章 过程_斐波那契数_05

 

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

第五章 过程_寄存器_06

 

 

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

第五章 过程_寄存器_07

 

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

第五章 过程_屏幕显示_08

 

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

第五章 过程_寄存器_09