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

1. 实验任务1
教材「实验9 根据材料编程」(P187-189)
编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。
程序:
 assume cs:code, ds:data
 data segment
     db 'welcome to masm!'
     db 00000010B,00100100B,01110001B ;颜色信息 绿色 绿底红色 白底蓝色
 data ends
 
 code segment
  start:
     mov ax, data
     mov ds, ax
 
     mov ax, 0b800H
     mov es, ax       ;设置显存段地址  
 
     mov cx,3        ;循环次数为3
     mov bx,0
     mov di, 1824       ;1764+64  附加短地址偏移地址
 
 s0:    push cx
     mov cx, 16       ;内存循环次数为16
     mov si, 0
 
 s1:    mov al, [si]
     mov es:[di], al
     mov al, [16+bx]
     mov es:[di+1], al
     inc si
     add di, 2
     loop s1
 
     pop cx
     inc bx
     add di,128
     loop s0
 
     mov ah, 4ch
     int 21h
 code ends
 end start

结果如下: 

 

分析:两个循环,外循环中颜色控制颜色信息的改变,内循环每次输入16个字符;

 

2. 实验任务2
编写子程序printStr,实现以指定颜色在屏幕上输出字符串。调用它,完成字符串输出。
子程序printSar
功能:以指定颜色在屏幕上(从屏幕左上角开始)输出字符串
要求:字符串以0结尾
入口参数
字符串的起始地址—> ds: si (其中,字符串所在段的段地址—> ds, 字符串起始地址
的偏移地址—> si
字符串颜色—> al
出口参数:无
使用任意文本编辑器,录入汇编源程序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
    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。
子程序num2str:
功能:把0~2559之间的任意整数转换成数字字符串,例如,把1984转换成'1984'
入口参数
要转换的整数 —> ax
数字字符串的起始地址 —> ds:di (其中:数字字符串所在段的段地址—> ds,字符串
起始地址的偏移地址—>di)
出口参数:无
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

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

子任务2
对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
mov al,2
call printStr

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
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

结果如下:
 

 

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实现的功能是?
  • 答:接收输入的字符串,“#”表示输入结束;cmp是比较指令,执行后对标志寄存器产生影响;je跳转函数,比较后相等则跳转。
  • line21-27实现的功能是? 
  • 答:将字符串输出到屏幕上。
5. 实验任务5
在visual studio集成环境中,编写一个简单的包含有函数调用的c程序。代码如下:
在line7, line13分别设置断点,在调试模式下,查看反汇编代码。
分析反汇编代码,从汇编的角度,观察高级语言中参数传递和返回值是通过什么实现的,以及,参数入
栈顺序,返回值的带回方式,等等。 
#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);
}

设置断点:

反汇编:

 

总结对这个简单的c代码反汇编后,你对反汇编出来的汇编指令分析的内容总结。可以包括但不限于一下内容的总结: 

答:参数传递和返回值是通过栈实现的;参数传递:形参参数入栈自右向左。先借助寄存器,将参数b 的地址压入堆栈寄存器eax,再将参数a 的值压入堆栈寄存器ecx

通过 call 指令调用函数sum,ret指令实现函数返回;每次调用需将原始的ss sp si di入栈,实现数据的暂存,返回后再将这些数据弹出,函数相当于子程序。

 

 

 

 

 
 

 

posted @ 2020-12-18 12:28  Dauntless_yin  阅读(107)  评论(2编辑  收藏  举报