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

实验任务1

源程序:  

assume cs:code, ds:data1
data1 segment
    db 02h,24h,71h
data1 ends

data2 segment
    db 77h,65h,6ch,63h,6fh,6dh,65h,20h,74h,6fh,20h,6dh,61h,73h,6dh,21h
data2 ends

data3 segment
    dw 072eh,07ceh,086eh
data3 ends

stack segment
    dw 0,0
stack ends
code segment
start:
    mov ax,data2
    mov ds,ax
    mov ax,0b800h
    mov es,ax

    mov cx,16
    mov bx,0
    mov si,072eh
    copy1:

    mov dl,ds:[bx]
    mov es:[si],dl
    mov byte ptr es:[si+1],02h
    inc bx
    add si,2
    loop copy1

    mov cx,16
    mov bx,0
    mov si,07ceh
    copy2:

    mov dl,ds:[bx]
    mov es:[si],dl
    mov byte ptr es:[si+1],24h
    inc bx
    add si,2
    loop copy2


    mov cx,16
    mov bx,0
    mov si,086eh
    copy3:

    mov dl,ds:[bx]
    mov es:[si],dl
    mov byte ptr es:[si+1],71h
    inc bx
    add si,2
    loop copy3

    mov ah, 4ch
    int 21h
code ends
end start

程序说明:本来想用二重循环直接将三行数据复制到显存区,但是需要用到的段寄存器太多不够用了,保存到栈中又太麻烦,所以直接写了三重循环,将数据的字型信息、颜色信息复制到现存区域。同时显存区域的设置是根据事先选定好的位置设置的。

编译、连接源程序:

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

程序运行结果:

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

实验任务2

修改后的源程序:

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

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

    mov si, offset str
    mov al, 4
    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

程序修改前的运行结果:

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

 

 

 程序修改后的运行结果:

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

问题一:

在调用子程序时将与主程序中的一些寄存器中的数据保存到栈中,在子程序返回前再将这些数据从栈中弹出回到寄存器中,实现数据的保存保护,防止数据丢失。

问题二:

将cx寄存器中保存的数据的颜色信息和字型信息复制到es段寄存器和di偏移地址寄存器所指示的显存地址区域中。

实验任务3

子任务1的编译、连接、运行程序:

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

 

 

 子任务1的反汇编和查看数据:

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

 

 

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

 

 

 子任务2修改完善后的代码:

assume cs:code, ds:data
data segment
        x dw 1999
        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 ax, data
    mov ds, ax
    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

子任务2程序的运行测试:

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

 

 

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

实验任务4

程序源代码:

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

运行测试截图:

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

问题一:

从键盘接收字符串,如果接收到字符'#'则跳转到next程序段执行下面的程序,否则继续接收字符并保存到ds:[si]中,si记录了字符串的长度。

问题二:

将si中保存到字符串长度数据传送到寄存器cx中,作为循环的次数。然后依次输出从ds:[0]开始的字符信息,循环次数为字符串的总长度。

实验任务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分别设置断点,在调试模式下,查看反汇编代码。line6的反汇编代码如下图所示:

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

在调试模式下,查看反汇编代码:

line7的反汇编代码如下图所示:

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

 

 line13的反汇编代码如下图所示:

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

 

 

分析反汇编代码,从汇编的角度,观察高级语言中参数传递和返回值是通过什么实现的,以及,参数入栈顺序,返回值的带回方式,等等。

1)从汇编的角度来看,高级语言中参数传递和返回值都是通过栈实现的,数据从ptr [b]、ptr [a]传入eax、ecx等寄存器。

2)调用函数时,形参参数入栈自右向左。先借助寄存器,将参数b 的地址压入堆栈寄存器eax,再将参数a 的值压入堆栈寄存器ecx。

3)通过call命令调用sum函数,最后返回真正的值为eax,再传入双字数据ptr[c],函数的返回值放在eax寄存器中,调用ret指令返回。

 

上一篇:汇编语言(王爽)学习记录_第五章


下一篇:汇编语言(王爽)学习记录_第六章