zoukankan      html  css  js  c++  java
  • 实验三

     

    实验结论:

    练习一:

    第一步(编写t1.asm源文件):

    在路径D:\masm下创建文本文档,在其中打入如下代码:

    assume cs:code

     code segment

             mov ah,2H

             mov dl,3H

             add dl,30H

             int 21H

            

             mov ah,2H

             mov dl,6H

             add dl,30H

             int 21H

             mov ax,4c00H

             int 21H

     code ends

    end

    第二步(使用dosbox对源文件进行编译、连接、执行):

    此处使用一个批处理文件process.bat对源文件进行编译、连接:

    编译、连接过程如下图:

    生成exe文件:

    清屏并执行t1.exe(如下图):

     

    得到输出结果:两个数字3和6。

    第二步:将 4 和9行 中寄存器 dl 的值分别修改为5和7,并重新汇编→ 连接→运行,观察结果的变化(如下):

     

    输出结果为5和7。

    第三步:用 debug 对生成的可执行文件 t1.exe 进行调试。

    使用r命令查看当前状态下的各寄存器中的值(如下图):

     

    发现cx中的值为17h,为十进制中的23,在查看所写代码的长度恰好为23个字节,ds和cs中的值分别为075A和076A,恰好满足cs=ds+10h。

    第四步:查看PSP(程序段前缀)的头两个字节,验证是否为CD和20

     

    第五步:使用 u 命令对 t1.exe 进行反汇编,观察反汇编得到的源代码:

     

    第六步:使用 t 命令和 p 命令(遇到 int 命令时,用 p 命令)单步调试,观察结果:

     

     

    由此可发现屏幕上显示的5和7并不是五十七,而是分次输出的5和7,原理是将需要输出的数据放入dl中,输出就是将dl中的数据通过ascll码转为对应的字符,并显示在屏幕上。

    练习二:

    第一步(编写t2.asm源文件):

    在路径D:\masm下创建文本文档,在其中打入如下代码:

    assume cs:code

     code segment

             mov ax,0b800H

             mov ds,ax

            

             mov bx,0H

             mov [bx],0433h

            

             mov bx,2H

             mov [bx],0436h

             mov ax,4c00H

             int 21H

     code ends

    end

    写完之后保存为asm文件。

    第二步(使用dosbox对源文件进行编译、连接、执行):

    此处使用一个批处理文件process.bat对源文件进行编译、连接:

    编译、连接过程如下图:

    编译生成obj文件:

     

    连接生成可执行的exe文件:

     

    清屏之后执行t2.exe:

     

    通过对程序运行结果的观察发现在屏幕左上角出现了红色的36。

    第三步:重新打开t2.asm并将7行和10行赋给[0]和[2]的值改为0432h和0439h,再次对t2.asm进编译、连接、执行:

    执行结果如下图:

     

    第四步:将t2.asm文件中的7和10行中赋给[0]和[2]的值改为0333h和0336h后,对t2.asm进行汇编、连接、执行:

    结果如下图:

     

    得到蓝色的36。

    猜想:0b800h这个段地址是文本模式显示内存的段地址,通过对其中写出字型数据,就可以使屏幕上显示对应的数值并控制数值的颜色。

    尝试:将t2.asm改写为以下的内容:

    assume cs:code

     code segment

             mov ax,0b800H

             mov ds,ax

            

             mov bx,0H

             mov [bx],0333h

            

             mov bx,2H

             mov [bx],0436h

            

             mov bx,4H

             mov [bx],0237h

             mov ax,4c00H

             int 21H

     code ends

    end

     

    注:令数据段寄存器中所存储的数据为b800h之后,从偏移地址为0的地方依次向内存单元写入数据,发现低位字节用来控制输出什么字符,高位字节用来控制输出的字符的颜色。

    在此基础上继续对t2.asm进行更改:更改如下:

    assume cs:code

     code segment

             mov ax,0b800H

             mov ds,ax

            

             mov bx,1H

             mov [bx],0333h

            

             mov bx,3H

             mov [bx],0436h

            

             mov bx,5H

             mov [bx],0237h

             mov ax,4c00H

             int 21H

     code ends

    end

    更改后的代码与原代码的区别在于:人为的向内存中写入数据不再是从偏移地址为0处开始写的,而是从偏移地址为1处开始写,对更改过的t2.asm进行汇编、连接、执行(执行结果如下图):

     

    出现问题,输出并不是不同颜色的367,而是其他字符,对修改过的t2.exe进行debug,查看b800相关偏移地址中存放的数据是什么(如下图):

     

    执行完了t2.exe之后对b800:0到b800:6中的数据进行查看:发现对对应偏移地址的数据写入确实成功了,并且右侧确实按照ascll码显示出了3,6,7这三个数字,但是屏幕左上角出来的的字符中并没有367,显示出来的字符是从偏移地址为0处开始2个2个向后看,每看两个在屏幕上显示一个字符。

    经过验证:[0]中存放的字型数据3320h(在debug对内存的查看,发现20这个字节数据并没有字符和它对应如图:

     

    )就是蓝色块,[2]中的3603h就是出现的蓝色背景的红心图案,而[4]中存放的3704h就是背景为蓝色的灰色菱形图案,[6]中存放的0702h就是灰色笑脸图案。

    另外:在尝试的过程中,给以b800位段地址的偏移地址[bx]赋值的时候,好像只可以传字型数据,如果传送字节型数据,会报severe error错误。

    再次改变t2.asm中的代码如下:

    assume cs:code

     code segment

             mov ax,0b800H

             mov ds,ax

            

             mov bx,2H

             mov [bx],0333h

            

             mov bx,4H

             mov [bx],0436h

            

             mov bx,6H

             mov [bx],0237h

             mov ax,4c00H

             int 21H

     code ends

    end

    结果如图:

     

    成功地将367显示出来,猜想得到验证。

    附:

    在集成实验环境下运行t2.asm

    打入代码保存运行:报错A2070

     

    经过查阅资料发现:在使用mov指令时最规范的写法是将操作数的长度规定好(即类型的强制转换)。

    原代码:

     

    改过后的代码:

     

    经修改,运行成功(如下):

     

    实验感悟:

    练习一:通过对d中数据的操作,了解到通过给dl赋值可以在屏幕上打印dl中所存的数据对应ascll码的字符。以及cs和ds中数据的关系、cx中存放数值的意义。

    练习二:通过对t2代码的改写,了解到:b800h是文本模式显示内存的段地址,并且对字符的显示是从0偏移地址开始的,并且是按字数据读取(高位字节控制属性,低位字节控制显示字符)。

    与实验一练习四的对比:

    实验一中要求从b810:0处通过e命令开始向内存写入数据,练习二中使用的是改变ds寄存器中的值为b800,并通过[address]来实现向内存中写入数据,但它们本质上都是改变内存中的数据。并且还发现:b8000h和b8100h这两个物理地址位于同一个段(b800:0~b800:ffff)中。(思考:这一个地址段的作用是什么?这一个地址段是文本模式显示内存吗?从字面意思对应到实验过程,确实发现这一个地址段可以实现文本+模式+显示的作用)

     

  • 相关阅读:
    LeetCode 282. Expression Add Operators (Hard,递归分治)
    LeetCode 279. Perfect Squares
    LeetCode 278. First Bad Version
    LeetCode 275. H-Index II
    工作笔记——使用Jest时遇到的一些问题
    RFC2616-HTTP1.1-Header Field Definitions(头字段规定部分—译文)
    RFC2616-HTTP1.1-Status Code(状态码规定部分—译文)
    RFC2616-HTTP1.1-Methods(方法规定部分—译文)
    RFC2616-HTTP1.1-Status Code(状态码规定部分—单词注释版)
    RFC2616-HTTP1.1-Methods(方法规定部分—单词注释版)
  • 原文地址:https://www.cnblogs.com/tomori/p/9971177.html
Copyright © 2011-2022 走看看