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

实验任务1

task4-1.asm:

assume cs:code,ds:data
data segment
      db 'welcome to masm!'
      db 02h,24h,71h                          ;三种颜色对应的16进制代码
data ends
code segment
start:
        mov ax,data
        mov ds,ax

        mov ax,0b800h
        mov es,ax                                 ;设置显存段地址

        mov di,1824                             ;附加段数据的偏移地址
        mov bx,16                                ;获取颜色的偏移地址
        mov cx,3                                  ;设置循环次数为3

s0:
        mov dx,cx                                ;将外层循环的cx值保存在dx中
        mov si,0                                   ;设置段数据的偏移地址
        mov cx,16                                ;设置内层循环次数为16

s:
        mov al,[si]                                ;获取字符数据
        mov ah,[bx]                              ;获取颜色数据
        mov es:[di],ax                           ;将彩色字符数据写入显存
        add di,2                                    ;附加段偏移地址增加2,便于下一个彩色字符的写入
        inc si                                         ;取下一个字符数据
        loop s

        add di,128                                 ;写入下一行
        inc bx                                        ;取另一种颜色属性
        mov cx,dx                                  ;用dx存放的外层循环的计数值恢复cx
        loop s0                                      ;外层循环的loop指令将cx中的计数值减1

        mov ax,4c00h
        int 21h
code ends
end start

运行结果:

 

 

实验任务2

task4-2.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

运行结果:

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

         这组对称使用的push、pop是为了防止在进行修改后出现问题却又无法回到原始位置。

  • line30的功能是什么?

         line30的功能是将彩色字符存入显存中。

 

 

实验任务3

task4-3.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

使用u命令进行反汇编:

使用g命令执行到line15(程序退出之前):

使用d命令查看数据段内容:

 

完善后的task4-3.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 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

运行结果:

 

把line3中的整数改成0-2559之间的任意数,运行结果:

 

 

实验任务4

task4-4.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

运行结果:

 

  • line12-19实现的功能是?

          line12-19实现的功能是接收输入的字符串,知道输入一个“#”表示输入结束。

  • line21-27实现的功能是?

          line21-27实现的功能是将之前输入的字符串显示到屏幕上。

 

 

实验任务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分别设置断点:

反汇编:

#include<stdio.h>
int sum(int,int);

int main(){
003913B0  push        ebp  
003913B1  mov         ebp,esp  
003913B3  sub         esp,0E4h  
003913B9  push        ebx  
003913BA  push        esi  
003913BB  push        edi  
003913BC  lea         edi,[ebp-0E4h]  
003913C2  mov         ecx,39h  
003913C7  mov         eax,0CCCCCCCCh  
003913CC  rep stos    dword ptr es:[edi]  
    int a=2,b=7,c;
003913CE  mov         dword ptr [a],2  
003913D5  mov         dword ptr [b],7  

    c=sum(a,b);
003913DC  mov         eax,dword ptr [b]  
003913DF  push        eax  
003913E0  mov         ecx,dword ptr [a]  
003913E3  push        ecx  
003913E4  call        sum (39105Ah)  
003913E9  add         esp,8  
003913EC  mov         dword ptr [c],eax  

    return 0;
003913EF  xor         eax,eax  
}
003913F1  pop         edi  
003913F2  pop         esi  
003913F3  pop         ebx  
003913F4  add         esp,0E4h  
003913FA  cmp         ebp,esp  
003913FC  call        @ILT+305(__RTC_CheckEsp) (391136h)  
00391401  mov         esp,ebp  
00391403  pop         ebp  
00391404  ret
int sum(int x,int y){
00391420  push        ebp  
00391421  mov         ebp,esp  
00391423  sub         esp,0C0h  
00391429  push        ebx  
0039142A  push        esi  
0039142B  push        edi  
0039142C  lea         edi,[ebp-0C0h]  
00391432  mov         ecx,30h  
00391437  mov         eax,0CCCCCCCCh  
0039143C  rep stos    dword ptr es:[edi]  
    return (x+y);
0039143E  mov         eax,dword ptr [x]  
00391441  add         eax,dword ptr [y]  
}
00391444  pop         edi  
00391445  pop         esi  
00391446  pop         ebx  
00391447  mov         esp,ebp  
00391449  pop         ebp  
0039144A  ret

总结:

       从汇编角度看,高级语言中参数传递是通过栈实现的,即将参数入栈保存到内存单元中,然后使用寄存器来使参数出栈调用;返回值是存入到eax中实现。参数的入栈顺序是后定义的数据先入栈。

posted @ 2020-12-18 01:37  腓腓  阅读(106)  评论(1)    收藏  举报