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

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

assume cs:code, ds:data, ss:stack
data segment
    db 'welcome to masm!'                       
    db 02H, 0A4H, 71H, 0000000000000    
    dw 12*160+6413*160+6414*160+6400000
data ends
stack segment         
    dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:
    mov ax, stack     
    mov ss, ax      
    mov sp, 16
mov ax, data      
mov ds, ax
mov ax, 0B800H      
mov es, ax
mov cx, 3       
mov bx, 16      
mov di, 32      
s0:  push cx            
    mov cx, 16    
    mov bp, [di]       
    mov si, 0






s1: 
    mov al, [si]       
    mov ah, [bx]       
    mov es:[bp], ax
inc bp
inc bp          
inc si          
loop s1
pop cx
add bx, 1    
add di, 2      
loop s0
mov ax,4c00H
int 21H
code ends
end start

 

根据已学知识,分别设置数据段保存字符的ASCII值,字符的位置,和背景及颜色的控制。根据前几次实验的经验,取8个字节的空间作为栈空间以实现循环。

通过嵌套循环实现对显存区域的输送。

根据要求计算送入区域应该为第12行,13行,14行,列偏移位置应该为160/2-16(字符串一共16个字节),所以偏移地址为: 12*160+64, 13*160+64, 14*160+64

实际效果如下:

assume cs:code, ds:data
data segment
    str1 db 'try', 0
data ends

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

    mov si, offset str1
    mov al, 2
    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

结果:

 

 

 

 

 

 对源程序做如下修改: 把line3改为:

str db 'another try', 0

把line12改为:

mov al, 4

 

 

基于运行结果,理解源代码,以及,组合使用转移指令call和ret实现子程序的原理与方法。具体地,在

line18-40中:

   line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?

  答:保存子程序运行前各寄存器的值,在子程序运行完毕后,将各寄存器中的值恢复子程序运行前的状态。

  line30的功能是什么?

  答:将字符及其颜色属性输入到指定的显存中,即打印到屏幕中。

 

3. 实验任务3

使用任意文本编辑器,录入汇编源程序task3.asm。

代码:

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

code segment
start:  
        mov ax, data
        mov ds, ax
        mov ax, x
        mov di, offset str1
        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
s2:        
        pop dx
        or dl, 30h
        mov [di], dl
        inc di
        loop s2
        
        pop dx
        pop cx
        pop bx
        pop ax

        ret
code ends
end start

阅读源代码,理解子程序num2str的汇编实现。

子任务1 对task3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行 到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串'1984'存放 在数据段中str标号后面的单元。

子任务2 对task3.asm源代码进行修改、完善,把task2.asm中用于输出以0结尾的字符串的子程序加进来, 实现对转换后的字符串进行输出。

子任务1:

 

 

可见已将转换后的字符串存入了str的内存单元中

子任务2:

代码:

assume cs:code, ds:data

data segment

        x dw 1984

        str1 db 16 dup(0)

data ends

 

code segment

start: 

        mov ax, data

        mov ds, ax

        mov ax, x

        mov di, offset str1

        mov si,0

        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

s2:       

        pop dx

        or dl, 30h

        mov [di], dl

        mov dh,2

        mov ax,0b800h

        mov es,ax

        mov es:[si],dx

        add si,2

        inc di

        loop s2

       

        pop dx

        pop cx

        pop bx

        pop ax

 

        ret

code ends

end start

 

 

将line3的数值改成 2000后,得到结果如下:

 

 将line3的数值改成 2020后,得到结果如下:

 

 

4. 实验任务4

使用任意文本编辑器,录入汇编源程序task4.asm。

 代码:
assume cs:code, ds:data
data segment
        str1 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# 得到结果如下:

 

 

汇编、链接、运行程序,输入一个字符串并以#结束(比如,2020, bye#)观察运行结果。结合运行结 果,理解程序功能,了解软中断指令。
具体地:
  line12-19实现的功能是?
  答:利用软中断指令,利用int21h的1号子功能,若当前输入的字符不是'#',将从键盘输入的字符存到指定的栈段中。
 
  line21-27实现的功能是?
  答:向标准输出设备(如屏幕)输出栈段中的内容。
 
5. 实验任务5
在visual studio集成环境中,编写一个简单的包含有函数调用的c程序。
代码如下:
#include <stdio.h>
int sum(int, int);
int main() {
int a = 2, b = 7, c;
c = sum(a, b);
return 0;
}
int sum(int x, int y) {
return (x + y);
}

在line7, line13分别设置断点,在调试模式下,查看反汇编代码。 分析反汇编代码,从汇编的角度,观察高级语言中参数传递和返回值是通过什么实现的,以及,参数入 栈顺序,返回值的带回方式,等等。

 

 

分析:
通过反汇编代码可以看出,高级语言的参数传递是通过寄存器实现的。在调用sum函数时,将存在寄存器中的变量值通过mov命令传给了形参,实现了值传递。int类型的返回值是从eax返回的。

 

posted @ 2020-12-18 11:39  dawei99  阅读(61)  评论(0)    收藏  举报