实验4 汇编应用编程和c语言程序反汇编分析

四、实验结论

  1. 实验任务1
    源程序
assume cs:code, ds:data
data segment
	     db 'welcome to masm!'
	     db 2h,24h,71h
	;绿色       0,000,0,010B    2H
	;绿底红色   0,010,0,100B    24H
	;白底蓝色   0,111,0,001B    71H

	     dw 0720h, 07C0h, 0860h
	;以B800H作为段地址,则一屏25行。中间的3行(11,12,13行):
	;11 1760~1919 中间32位为b800:0720~b800:0740
	;12 1920~2079 中间32位为b800:07C0~b800:07E0
	;13 2080~2239 中间32位为b800:0860~b800:0880
data ends

code segment
	start:
	      mov  ax, data
	      mov  ds, ax
	      mov  ax, 0b800H
	      mov  es, ax

	      mov  di,0
	      mov  ah,ds:[di+10h]
	      mov  al,ds:[di+11h]
	      mov  bh,ds:[di+12h]
	      mov  si,0
	      mov  cx,16
	s:    mov  bl,ds:[si]
	      mov  es:[di+0720h],bl
	      mov  es:[di+0721h],ah
	      mov  es:[di+07C0h],bl
	      mov  es:[di+07C1h],al
	      mov  es:[di+0860h],bl
	      mov  es:[di+0861h],bh
	      inc  si
	      add  di,2
	      loop s

code ends
end start

运行结果截图

  1. 实验任务2
    源程序
assume cs:code, ds:data
data segment
    ;str db 'try', 0
    str db 'another try', 0
data ends

code segment
start:  
	mov ax, data
	mov ds, ax

	mov si, offset str
	;mov al, 2
	mov al, 4
	call printStr

	mov ah, 4ch
	int 21h

printStr:
	push bx
	push cx
	push si
	push di

	mov bx, 0b800H
	mov es, bx
	mov di, 0
s:      mov cl, [si]
	mov ch, 0
	jcxz over
	mov ch, al
	mov es:[di], cx
	inc si
	add di, 2
	jmp s

over:   pop di
	pop si
	pop cx
	pop bx
	ret

code ends
end start

运行结果截图

line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?
为了保存程序跳转前的状态

line30的功能是什么?
在显存中写入字符数据及颜色信息

  1. 实验任务3

子任务1的反汇编截图

子任务2修改、完善后的完整汇编源代码,及,运行测试截图

assume cs:code, ds:data
data segment
        x dw 1984
        str db 16 dup(0)
data ends

code segment
start:
        mov ax, data
        mov ds, ax
        mov ax, x
        mov di, offset str
        call num2str

        mov ah, 4ch
        int 21h

num2str:
        push ax
        push bx
        push cx
        push dx

        mov cx, 0
        mov bl, 10
s1:
        div bl
        inc cx
        mov dl, ah
        push dx
        mov ah, 0
        cmp al, 0
        jne s1

        mov ax,0b800h
        mov es,ax
        mov si,0
        mov ah,2h
s2:
        pop dx
        or dl, 30h
        mov [di], dl
        mov es:[si],dl
        mov es:[si+1],ah
        add si,2h
        inc di
        loop s2

        pop dx
        pop cx
        pop bx
        pop ax

        ret
code ends
end start

  1. 实验任务4
    程序源代码
assume cs:code, ds:data
data segment
        str db 80 dup(?)
data ends

code segment
start:  
        mov ax, data
        mov ds, ax
        mov si, 0

s1:        
        mov ah, 1
        int 21h
        mov [si], al
        cmp al, '#'
        je next
        inc si
        jmp s1
next:
        mov cx, si
        mov si, 0
s2:     mov ah, 2
        mov dl, [si]
        int 21h
        inc si
        loop s2

        mov ah, 4ch
        int 21h
code ends
end start

运行测试截图

回答任务中提出的两个问题
line12-19实现的功能是
从键盘中输入单个字符,保存到数据段中,遇到#则输入结束
line21-27实现的功能是
在屏幕上逐字符输出数据段的内容

  1. 实验任务5

在主函数main内,先进行初始化操作,将默认堆栈寄存器压入栈。然后进行变量声明,若变量有初值,则反汇编就会为其生成一条 Mov指令为其赋值,对于没有初值的变量其每个字节都为0xCCH。
调用函数时,形参参数入栈自右向左。先借助寄存器,将参数b 的地址压入堆栈寄存器eax,再将参数a 的值压入堆栈寄存器ecx。实现了实参赋值给形参,通过 call 指令调用函数sum。
sum函数内同样先初始化并分配栈空间,执行得到的结果保存在eax寄存器内,调用ret指令返回。
执行完毕,返回主函数main,再将eax值赋值给参数c。主调函数根据压入堆栈的参数的数目 2 和参数大小,利用指令 add ESP,8 将参数全部弹出。此时堆栈就恢复到其调用前的状态。

posted @ 2020-12-18 00:13  Ranye123  阅读(27)  评论(1编辑  收藏  举报