第五章 过程

 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

posted @ 2019-09-19 09:27  Hk_Mayfly  阅读(279)  评论(0编辑  收藏  举报