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

1. 实验任务1

源程序:

assume cs:code, ds:data
data segment
    db 'welcome to masm!'
data ends

code segment
start:
    ;数据段指向字符
    mov ax, data
    mov ds, ax

    mov si, 0
    mov di, 0
    mov cx, 16

    ;附加数据段指向显存缓冲区
    mov ax, 0b800h
    mov es, ax
s:
    ;获取需要打印的字符
    mov al, ds:[si]
    
    ;确定字符样式
    mov ah, 02h
    ;确定行数与列数
    mov es:[64+di+1760], ax

    mov ah, 24h
    mov es:[64+di+1920], ax

    mov ah, 71h
    mov es:[64+di+2080], ax

    ;指向下一个字符
    inc si
    ;指向缓冲区中下一个字
    add di, 2

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

运行结果截图:

2. 实验任务2

源程序

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,这样用的目的是什么?
line19-22 是为了保存子函数中用到的寄存器数据。
line36-39 是为了在回到调用处前恢复修改的寄存器数据。

line30的功能是什么?
将以al为字符样式的字符写入显存缓冲区中。

3. 实验任务3

反汇编截图:

执行line15之前

查看结果

修改、完善后的完整汇编源代码

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

程序源代码:

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实现的功能是?
从键盘中读取字符并写入数据段,直到读入到字符#停止,字符数量存在si中。

line21-27实现的功能是?
打印从键盘中读取存在数据段中的字符。

5. 实验任务5

源程序

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

设置断点

反汇编

从反汇编结果中可知,函数调用参数会存储于寄存器中然后压入栈中,再使用call跳转,并且为两次跳转。
函数的返回值存放再eax寄存器中。
参数的入栈顺序为从右往左入栈。
函数调用栈由ebp寄存器所控制,函数调用前压入栈中并改变栈顶,调用完成恢复原值。

posted @ 2020-12-16 22:56  openseem  阅读(88)  评论(0)    收藏  举报