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

实验4 汇编应用编程和c语言程序反汇编分析
实验任务一
代码为:

assume cs:code, ds:data, ss:stack

data segment
    db 'Welcome to masm!'           
    db 02H, 0A4H, 71H, 0, 0, 0, 0, 0    
    dw 1824, 1984, 2144, 0, 0, 0, 0, 0  
data ends

stack segment
    dw 0, 0, 0, 0, 0, 0, 0, 0       
stack ends

code segment
start:
    mov ax, data            
    mov ds, ax
    mov ax, stack               
    mov ss, ax
    mov sp, 16
    mov ax, 0B800H              
    mov es, ax
    
    mov cx, 3               
    mov bx, 16              
    mov di, 24              

s0:    push cx                 
    mov cx, 16              
    mov bp, ds:[di]            
    mov si, 0              

s1:    mov al, ds:[si]            
    mov ah, ds:[bx]             
    mov es:[bp], ax             
    add bp, 2               
    inc si
    loop s1

    pop cx                  
    add bx, 1              
    add di, 2               
    loop s0

    mov ax, 4c00H
    int 21H
code ends
end start

结果为:

实验任务二
代码为:

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

结果为:
修改后的结果为:

line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?
暂存父程序的cx的值,避免影响子程序的循环,通过push pop来保存现场。
line30 的功能是什么
ds:[si]内的字符如果为0,则放入cl的时候,cx为0,自动跳出循环, 从而使实现读完数据自动跳出,以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 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

链接并反编译结果如下:

经过调试并且用d命令查看后,1984确实放在数据str标号后

完善后代码如下:

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

结果如下:

修改,将1984修改为152后,结果如下

实验任务四
代码为:

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的功能:
读入字符,以 #为结束符

line21-27 的功能
把读入的字符串输出

实验任务五
代码为:

#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);
}

进行反汇编结果为:

反编译总结:
通过push eax,esi,edi等操作来保留现场,并且在push ecx 保留完毕以后call sum (027107Dh)来调用sum函数。说明函数的调用跟之前一样,都得用栈来保留数据,再进行调用,从来避免父进程对子进程的影响。

posted @ 2020-12-16 01:47  JJo_Nak  阅读(63)  评论(3)    收藏  举报