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

实验一

编辑代码如下:

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

code segment
start:    
    mov ax,data
    mov es,ax
    mov ax,0b800h
    add ax,110
    mov ds,ax
    mov cx,16
    mov bx,0
    mov si,0
s:    
    mov al,es:[bx]
    mov [bx+si+64],al
    mov byte ptr [bx+si+64+1],2
    mov [bx+si+64+160],al
    mov byte ptr [bx+si+64+160+1],100100b
    mov [bx+si+64+320],al
    mov byte ptr [bx+si+64+320+1],1110001b
    inc bx
    inc si
    loop s
        
    mov ax,4c00h
    int 21h
code ends
end start

解释

  • 在 data 中放入数 'welcome to masm!' ,并将data段地址传给 es 。
  • 将 80×25 彩色字符模式下的第 0 行显存空间的地址传递给 ds 寄存器,因为需要偏移 11 行,所以加上 110 ,使得 ds 段寄存器指向第 11 行。
  • 字符串长度是 16,所以设置 cx 寄存器为 16。
  • 在 data 数据段中字符串是单个字节存储的,输出到显存中需要中间空出一个来设置显示的颜色。取数据的时候用 bx ,输出的时候用 bx+si 。
  • 先将字符读到 al 中,再输出到相应的位置上,因为 al 寄存器是 8 位寄存器,所以读写都是单字节。再设置颜色,这里要设置单字节 “ byte ptr [ ] ” 。
  • 因为字符串长度是 16,需要 32 字节,而一行是 160 字节,所以可以计算出,要使得字符串居中显示,需要偏移 64 个字节。
  • 一行是 160 字节,输入下一行的内容,则需要偏移160 个字节。
  • 颜色设置,根据 “ 闪烁 R(背景) G(背景) B(背景) 高亮 R(前景) G(前景) B(前景) ” 相应的设置即可。绿色是00000010B,绿底红字是00100100B,白底蓝字是01110001B。

运行结果

试验二

编辑代码如下:

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,这样用的目的是:因为在子程序中需要使用这些寄存器,为了在程序使用 ret 命令返回后,寄存器中的值不变。所以需要,先将这些寄存器的值 push 到栈中,等子程序运行结束,再使用 pop 将原先的数值还原到寄存器中。
  • line30的功能是:将 cx 寄存器中的数值保存到 es:[di] 内存单元中。可以上问看出,cl 寄存器中存储是 data 段的段数据中 “str” ,ch 寄存器是 al 寄存器的数值,而es:[di] 内存单元就是 0b800:0 就是显存的位置。所以当前指令的作用就是将 data 段中的 “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 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

进行反汇编

把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

实验四

编辑代码如下:

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实现的功能:读入一个字符,将它存到 data 数据段中。同时,将读入的字符和 ‘ # ’ 进行比较,如果是 ‘ # ’ 跳到 next 标号处向下运行,否则继续读入下一个字符。
  • line21-27实现的功能:输出 data 数据段中的一个字符,循环字符串的数量次数。

试验五

在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分别设置断点,在调试模式下,查看反汇编代码。


  • 程序的参数传递都是通过寄存器来传递的
  • 函数的返回值,也是通过寄存器返回的
posted @ 2020-12-18 11:04  三水sanshuiii  阅读(131)  评论(3)    收藏  举报