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

目录


实验内容

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

分析过程:
首先,我们通过fan翻阅书籍查找属性字节的格式,在189页,得到显示字和背景颜色的属性字节:
绿色字:00000010B
绿底红字:00100100B
白底蓝字:01110001B
由于我们需要将字符显示在屏幕的中间,我们就需要计算出每一行字符的开始位置和结束位置。在85*25的彩色字符模式中,根据上表我们得到最中间三行的偏移地址,即11、12、13行的偏移地址。

注意每行可以显示80个字符,每个字符占据两个字节,低位控制显示字符的ASCII码,高位控制显示的属性字节。
同时我们知道我们需要显示的字符串的长度为16,那么三行字符各自的起始和结束位置分别为:
11:
起始位置 1824 结束位置 1856
12:
起始位置 1984 结束位置 2016
13:
起始位置 2144 结束位置 2176
前一行最后一个字符位置距离下一行起始字符位置差了128个字符,所以只需要外层一个循环控制显示的行,内层循环控制本行颜色设置和字符写入,内层循环结束向前移动128个字节,显示下一个字符,直到三行文字都显示完成。
据此,我们就能写出如下代码:

assume cs:code, ds:data
data segment
    db 'welcome to masm!' ;存放字符的数据
    db 01000000B, 00100100B, 01110001B  ;存放字符颜色属性的数据
data ends
code segment
start:mov ax, data
    mov ds, ax  
    mov ax, 0b800H
    mov es, ax  
    mov bx, 16  
    mov di, 1824  
    mov cx, 3  
s1: mov si, 0  
    push cx  
    mov cx, 16  
s2: mov al, ds:[si]  
    mov ah, ds:[bx]  
    mov es:[di], ax  
    add di ,2  
    inc si  
    loop s2
    add di, 128  
    inc bx  
    pop cx  
    loop s1
    mov ah, 4ch
    int 21h
code ends
end start

实验步骤:

1
task41.asm执行结果

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

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

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  
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
1
task42.asm执行结果
将line3修改为: str db 'another try',0; 将line12修改为: mov al,4;

修改之后的程序运行结果如下所示:

1
修改task42.asm执行结果
(1)line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么? 为了在子程序结束后,将四个寄存器的值恢复到进入子程序之前的状态,让程序能够继续正常运行。 (2)line30的功能是什么? line30为“mov es:[di],cx”,其中es寄存器存储的为b800h,偏移地址开始为0,cx寄存器的低位存储字符,高位存储属性字节,所以这行代码的功能就是将字符及其颜色放在显存中在屏幕上显示出来。

实验任务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

实验步骤:

1
反汇编查看‘1984’写入到str标号后面单元中
将task42.asm中用于输出字符串的子程序加进来实现对转换后字符串的输出。 源代码如下:
1 1
代码
1
反汇编查看‘1984’写入到str标号后面单元中

实验任务4
使用任意一款文本编辑器,编写8086汇编源程序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

实验步骤:

1
task44.asm运行结果
(1)line12-19功能? 答:功能为从键盘读入字符串,并将读入的字符存储到data数据段中,直到遇到符号‘#’.

(2)line21-27实现的功能是?
答:将存放在data数据段中的字符输出到显示屏上,也就是将键盘输入的字符输出到显示屏上。

实验任务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);
}

实验步骤:

1
line6反汇编
1
line11反汇编

总结:
在高级语言中,从汇编的角度来看,传递参数时通过栈实现的,同时靠近栈顶的参数是形参,靠近栈底的参数是实参,被调函数的返回值保存在eax寄存器中。参数的入栈顺序是b先入栈,然后a;而在被调用函数的执行过程中,a先被访问,然后是b。

posted @ 2020-12-18 09:26  qylh  阅读(147)  评论(1)    收藏  举报