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

1. 实验任务1

教材「实验9 根据材料编程」(P187-189)
编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。
 
结果如下:

 代码:

 1 assume cs:code, ds:data
 2 data segment
 3      db 'welcome to masm!' ;需要显示的字符
 4      db 02h,24h,71h ;颜色的16进制表示,00000010b,00100100b,01110001b
 5 data ends
 6 
 7 code segment
 8 start:  
 9     mov ax, data
10     mov ds, ax
11     
12     mov ax,0b800h;设置显存地址
13     mov es,ax
14     
15     mov di,1824;三句话中第一行字m所在列的偏移地址
16     mov bx,16 ;颜色的数据存放在字母的后面,在数据段的16个字节
17     mov cx,3;三行数据,循环3次
18 
19 s:  push cx;存储外层循环
20     mov si,0
21     mov cx,16;内存循环
22 
23 s1: mov al,ds:[si];低字节存储字符ASCII码
24     mov ah,ds:[bx];高字节存储字符属性
25     mov es:[di],ax
26     add di,2
27     inc si
28     loop s1
29     
30     pop cx;取出外循环
31     inc bx
32     add di,128;从上一行的'!'转到下一行的'w',因为每个字符包含字符的属性,所以一行字占32字节
33     loop s
34 
35     mov ah, 4ch
36     int 21h
37 code ends
38 end start

实现思路:在显存区域,以字符为单位显示,高位存储属性,地位存储ASCII码,因此该题目所占内存为32字节,一行为160个,所以在中间位置的话是64-96;

整屏幕共25行,所在行数为11-13,所以其实位置为11*160+64=1824;设置两个循环,来实现三行打印和遍历16个字母,;cx寄存器不够用,因此使用栈存储。

2. 实验任务2

编写子程序printStr,实现以指定颜色在屏幕上输出字符串。调用它,完成字符串输出。
运行结果:

 修改代码之后的运行结果:

基于运行结果,理解源代码,以及,组合使用转移指令call和ret实现子程序的原理与方法。具体地,在
line18-40中:
line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?
 
答:该程序调用子程序,为了不改变源程序中各个寄存器的值,先压栈保存在弹出了以便主程序后面使用。
 
line30的功能是什么?
 
答:将16位寄存器的值写入显存,显示在屏幕上。

3. 实验任务3

使用任意文本编辑器,录入汇编源程序task3.asm。
 1 assume cs:code, ds:data
 2 data segment
 3         x dw 1999
 4         str db 16 dup(0)
 5 data ends
 6 
 7 code segment
 8 start:  
 9         mov ax, data
10         mov ds, ax
11         mov ax, x
12         mov di, offset str
13         call num2str
14         mov si, offset str
15         mov al, 2
16         call printStr
17         mov ah, 4ch
18         int 21h
19 
20 num2str:
21         push ax
22         push bx
23         push cx
24         push dx
25         
26         mov cx, 0
27         mov bl, 10
28 s1:      
29         div bl
30         inc cx
31         mov dl, ah
32         push dx
33         mov ah, 0
34         cmp al, 0
35         jne s1
36 s2:        
37         pop dx
38         or dl, 30h
39         mov [di], dl
40         inc di
41         loop s2
42         
43         pop dx
44         pop cx
45         pop bx
46         pop ax
47 
48         ret
49 
50 
51 printStr:    push bx
52         push cx
53         push si
54         push di
55         mov bx, 0b800H
56         mov es, bx
57         mov di, 0
58 
59 s:          mov cl, [si]
60         mov ch, 0
61         jcxz over
62         mov ch, al
63         mov es:[di], cx
64         inc si
65        add di, 2
66         jmp s
67  
68 over:       pop di
69         pop si
70        pop cx
71       pop bx
72         ret
73 code ends
74 end start
子任务1
对task3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行
到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串'1984'存放
在数据段中str标号后面的单元。

-g命令运行到15行(退出去之前)结果截图:

 

子任务2
对task3.asm源代码进行修改、完善,把task2.asm中用于输出以0结尾的字符串的子程序加进来,
实现对转换后的字符串进行输出。
 
把task3.asm源代码中,line3中整数改成0~2559之间的任意数值,运行测试,观察结果。

4. 实验任务4

使用任意文本编辑器,录入汇编源程序task4.asm。
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
汇编、链接、运行程序,输入一个字符串并以#结束(比如,2020, bye#)观察运行结果。
line12-19实现的功能是?
 
答:将键盘键入的字符存入es寄存器,知道碰到#跳转到next部分,结束程序。
 
line21-27实现的功能是?
 
答:将键入的数据存入显存,显示在屏幕上。

5. 实验任务5

在visual studio集成环境中,编写一个简单的包含有函数调用的c程序。代码如下:
设置断点

 反汇编

 

 

 调用参数时是将参数先压栈,压栈的顺序不同的编译器会有区别,本例中从右到左,再使用call调用子程序,

程序调用完毕后,结果保存在eax中,当做返回值。

posted @ 2020-12-17 22:52  yoyoMasterLi  阅读(103)  评论(2编辑  收藏  举报