首页 > 编程语言 > 详细

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

时间:2020-12-18 10:22:06      阅读:26      评论:0      收藏:0      [点我收藏+]

一、实验目的

  1. 理解80×25彩色字符模式显示原理
  2. 理解转移指令jmp, loop, jcxz的跳转原理,掌握使用其实现分支和循环的用法
  3. 理解转移指令call, ret, retf的跳转原理,掌握组合使用call和ret/retf编写汇编子程序的方法,掌握参数传递方式
  4. 理解标志寄存器的作用
  5. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现分支和循环的用法
  6. 了解在visual studio/Xcode等环境或利用gcc命令行参数反汇编c语言程序的方法,理解编译器生成的反汇编代码
  7. 综合应用寻址方式和汇编指令完成应用编程
二、实验内容
1.实验任务1
编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串‘welcome to masm!‘。

assume cs:code
data segment
db ‘welcome to masm!‘
db 2,36,113
data ends
code segment
start:
mov ax,data
mov ds,ax


mov ax,0b86eH
mov es,ax
mov bx,0
mov cx,3

s1: push cx

mov cx,16
mov si,0
mov di,64
s: mov al,[si]
mov es:[di],al
mov al,[16+bx]
mov es:[di+1],al
inc si
add di,2
loop s

inc bx
mov ax,es
add ax,0ah
mov es,ax

pop cx
loop s1

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

运行结果:

技术分享图片

先将‘welcome to masm!‘存入data段所代表的内存空间,然后计算出需要显示的颜色的10进制数据放在‘welcome to masm!‘后面方便取数据时直接取出颜色属性。

代码段code:

将data的地址赋值给ds段寄存器,数据段寄存器指向目标数据存放的内存空间。
计算屏幕中间上一排对应的段地址为0b86eh,并将其赋值给额外的数据段寄存器es
mov bx,0 用bx记录当前输出行数
mov cx,3 需要输出三行,外层循环为3次
需要嵌套使用loop指令因此在执行显示时将当前cx压入栈,并标记为s1
内存循环:共16个字符,因此循环16次
计算输出到中间列的起始列偏移量为64,因此mov di,64,并将字符赋值到es:[di]
对应的颜色属性为[16+bx],将其赋值到es:[di+1]
一行输出结束后,进入下一行,将es+0ah
pop cx将cx值出栈进入下一循环显示下一行的数据。

2.实验任务2

编写子程序printStr,实现以指定颜色在屏幕上输出字符串。调用它,完成字符串输出。
  子程序printSar
  功能:以指定颜色在屏幕上(从屏幕左上角开始)输出字符串
  要求:字符串以0结尾
  入口参数
    字符串的起始地址—> ds: si (其中,字符串所在段的段地址—> ds, 字符串起始地址的偏移地址—> si字符串颜色—> al
    出口参数:无 
使用任意文本编辑器,录入汇编源程序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,这样用的目的用于保存和恢复寄存器的值。在用寄存器前先将寄存器的值入栈,保留原本寄存器的内容,使用完后出栈恢复寄存器里的内容,防止出现意外情况。line30的功能是设置字符颜色属性。

3.实验任务3

使用任意文本编辑器,录入汇编源程序3.asm。
  子程序num2str:
    功能:把0~2559之间的任意整数转换成数字字符串,例如,把1984转换成‘1984‘
    入口参数
      要转换的整数 —> ax
      数字字符串的起始地址 —> ds:di (其中:数字字符串所在段的段地址—> ds,字符串起始地址的偏移地址—>di)
    出口参数:无 
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

对3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串‘1984‘存放在数据段中str标号后面的单元。

结果:

技术分享图片

 对3.asm源代码进行修改、完善,把2.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
        call printfstr

        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

printfstr:
    push ax
    push bx
    push cx
    push si
    push di

    mov ax,2
    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
    pop ax
    ret
code ends
end start

实验结果:

技术分享图片

line3中整数改成0~2559之间的任意数值,运行测试,观察结果 

技术分享图片

 

 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
汇编、链接、运行程序,输入一个字符串并以#结束(比如,2020, bye#)观察运行结果。结合运行结果,理解程序功能,了解软中断指令。具体地:
运行结果:
技术分享图片
mov ah,1是功能号代表1号子程序,表示键盘输入并回显al(输入字符),int 21h 表中断。
line12-19实现的功能是循环读入,直到遇到‘#’跳转到next段执行其他指令。
mov ah,2是二号子功能,实现字符的输出,line21-27实现的功能是 输出刚才的字符。
5.实验任务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);
}
分别设置断点,在调试模式下,查看反汇编代码。
分析反汇编代码,从汇编的角度,观察高级语言中参数传递和返回值是通过什么实现的,以及,参数入栈顺序,返回值的带回方式,等等。
技术分享图片

 技术分享图片

 

 高级语言中参数传递,从汇编的角度是如何传递的,返回值是如何返回的;多个参数的入栈顺序是什么样的;函数调用栈

c = sum(a, b);

000918A6 mov eax,dword ptr [b] 
000918A9 push eax                    在调用sum函数之前将b指向的数据放入寄存器eax中并且保存进栈中
000918AA mov ecx,dword ptr [a] 
000918AD push ecx                    然后保存a指向的内存单元的数据到栈中并且放入寄存器ecx中
000918AE call sum (091096h)    调用sum函数
000918B3 add esp,8
000918B6 mov dword ptr [c],eax 将结果赋值给c指向的内存单元  说明返回值在eax中

return (x + y);
00091828 mov eax,dword ptr [x]  将x指向的内存单元的数据移入寄存器eax中
0009182B add eax,dword ptr [y]   将y指向的内存单元的数据和eax中的数据相加后放入寄存器eax中

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

原文:https://www.cnblogs.com/yu136/p/14152230.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!