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

实验结论

实验任务1

编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。

源码如下:

assume cs:code,ds:data
data segment
     db 'welcome to masm!'     
     db 00000010B      ;黑底绿字
     db 00100100B      ;绿底红字
     db 01110001B      ;白底蓝字
data ends;
 
stack segment stack
     db 128 dup(0)
stack ends
 
code segment
start:    mov ax,stack
            mov ss,ax
            mov sp,128
            
            mov bx,data
            mov ds,bx
            
            mov bx,0B800H
            mov es,bx
            
            mov si,0 
            mov di,160*11+32*2
            mov bx,16
            mov dx,0
            mov cx,3  ;循环3次,输出三行
            
m:        push bx
            push cx
            push si
            push di
            
            mov cx,16
            mov dh,ds:[bx] ;用dh存放颜色属性
            
s:         mov dl,ds:[si] ;dl存放数据
            mov es:[di],dx
            add di,2
            inc si
            loop s
            
            pop di
            pop si
            pop cx
            pop bx
            add di,160 ;实现换行
            inc bx ;bx改变一个字节
            loop m
            
            mov ax,4c00h
            int 21h           
code ends           
end start

结果截图展示:

实验任务2

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

源码如下:

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

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

    mov si, offset str
    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
再次汇编、运行程序,观察运行结果。

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

答:暂存对应寄存器的内容以便于子程序运行完毕后进行恢复。

问:line30的功能是什么?

答:将字符和对应颜色的信息存储到显存中。

实验任务3

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

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
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
在debug中使用u命令反汇编
使用g命令执行到line15(程序退出之前)
使用d命令查看数据段内容

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

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 si, offset str
        call  shuchu

        mov ah, 4ch
        int 21h

num2str:
        push ax
        push bx
        push cx
        push dx
        
        mov bx,0b800h
        mov es,bx
        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
shuchu :
        push ax
        push bx
        push cx
        push dx
        
        mov bx, 0b800H
        mov es, bx
        mov di, 0
        mov al,2
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

把task3.asm源代码中,line3中整数改成0~2559之间的任意数值,运行测试,观察结果。

实验任务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实现的功能是?

答:利用int 21h的1号子功能来实现若输入的不是#则入栈操作。

问:line21-27实现的功能是?

答:利用int 21h的2号子功能循环依次输出之前入栈的字符。

实验任务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设置断点,在调试模式下,查看反汇编代码:

 

高级语言的参数传递是通过寄存器实现的

这里可以看到b先入栈然后是a,所以是从右往左入栈

先将参数b 的值存入寄存器eax,再压入堆栈,再将参数a 的值存入寄存器ecx,再压入堆栈。

通过call命令调用sum函数,返回值通过eax寄存器带回。

posted @ 2020-12-16 22:43  schedinger  阅读(116)  评论(1)    收藏  举报