实验1 用机器指令和汇编指令编程

 

实验1.1 查看CPU和内存,用机器指令和汇编指令编程

实验任务

(1)使用Debug,把以下程序段写入内存,逐条执行,观察每条指令执行后CPU中相关寄存器中的内容变化。

  • b8 20 4e  mov ax,4e20
  • 05 16 14  add ax,1416
  • bb 00 20  mov bx,2000
  • 01 d8  add ax,bx

   写入指令前的内存单元:

        

  用e命令以机器码形式写入前两条指令:

  

  用a命令以汇编指令形式写入后两条指令:

   

  使用d命令查看内存中被写入的指令:

  

   使用u命令反汇编内存中被写入的指令:

  

  使用t命令逐步执行指令,观察内存单元的变化:

  

   所有指令执行完毕后,寄存器AX=8236,BX=2000,CS=0000,IP=020B。

(2)将以下3条指令写入从2000:0开始的内存单元,利用这三条指令计算2的8次方。

  • mov ax,1
  • add ax,ax
  • jmp 2000:0003

   首先通过r指令修改CS、IP的值为2000和0:

  

 

  将3条指令写入内存单元:

 

  

 

  

 

   从2000:0003开始,使用t命令执行至2000:0007连续执行

   

  
  注意此处AX=0100为16进制表示,用10进制表示即为256即2的8次方。

(3)查看内存中的内容

  PC机主板上的ROM中写有一个生产日期,在内存FFF00H~FFFFFH的某几个单元中,尝试找到这个生产日期并试图改变它。

   

   在FFF0:00F0处找到生产日期1992.01.01。注:此处为DOSBox虚拟环境下的生产日期。

   试图修改该日期,发现无效。

  

   分析:地址C0000~FFFFF的内存单元为只读存储器地址,向其中写入内容是无效的。

(4)向内存从B8100H开始的单元中填写数据,观察产生的现象。如:

    -e B810:0000 01 01 02 02 03 03 04 04

  

   

  分析:地址A0000~BFFFF的内存单元是现存的范围,向其中写入数据,这些数据就会被显卡输出到显示屏上。在这个过程中,内存地址决定了像素点的位置,一个字节中的高4位决定符号的形状,而后四位决定符号的颜色。

——————————————————————————————————————————————————————————————————

实验1.2 寄存器的内存访问

实验任务

(1)使用e命令修改内存单元 0020:0~0020:f 中的数据,并查看该修改操作是否正确写入数据。

  

  如图,写入数据正确。

(2)将P74页的程序写入内存,逐条调试,根据指令执行后的实际运行结果填空。

   使用a指令写入程序:

    

   单步调试:

    

    

    

  过程分析:前两条指令,意在将ds即数据区寄存器的地址设为ffff,在这之后对于内存地址的调用[X],即可看作读取地址ds:x单元处的数据。

            第3、4条指令,意在将栈底设置为2200,在执行第四条指令时,紧接执行了其下的第五条指令mov sp,0100设置栈顶位置。

         第7~10条指令,借助ds数据区寄存器对于内存中的内容进行查改设定。

        第11~14条指令,通过对于ax、bx的出栈入栈操作,实质上执行了交换ax、bx寄存器的内容。这里的push和pop指令利用到了栈地址和 栈顶指针,即先前设置的ss:sp。

       第15~16条指令,对于栈的一些使用。

 (3)将图3.19的7行指令写入内存,进行一些修改操作,并分析原因。

    将指令写入内存:

      

   使用e命令修改2000:0~2000:f的值为0:

      

   逐步调试:

      

 

 

       

       

    内存分析:首先我们将2000:0~2000:f设置为了0,但经过mov sp,ax 和mov sp,10指令后,此时初始的栈底为2000,栈顶为2000:10我们发现,虽然我们还没有向栈内push内容,但2000:0~2000:f这段内存中被写入了一些内容,包括CS和IP寄存器的值被放在栈后,以及在此 状态下的AX值。经过两次压栈操作,我们可以通过查看内存看见,ax的值被正确的压入栈中,如果在程序执行完毕后继续执行空程 序,栈后保存的CS、IP值也随之变化,

    成因猜测:可能栈在创建过程中会保留记录当时的CS、IP值和一些寄存器的状态,同时在对栈进行操作的过程中,机器会动态维护这些状态。

 

实验总结:

  通过本次实验,我从以下几个方面认识了汇编语言:

  1.   常用的debug指令的使用
    1.   -a cs:ip  在cs:ip中写入指令
    2.   -r  [寄存器]  观察寄存器状态[修改寄存器的值]
    3.        -d [内存地址] [l长度] 观察内存地址中指定长度的内容
    4.        -u [内存地址] [l长度] 将内存地址中指定长度的二进制数据反汇编成汇编语言。
    5.        -e [内存地址] 修改指定内存地址的内容
    6.        -t[=内存地址] 从指定内存地址开始单步执行汇编指令
  2.   各种寄存器的作用
    1.   AX、BX、CX、DX通用寄存器,长16位,其中可以分为AH、AL两个8位寄存器使用
    2.        SS、SP栈底寄存器和栈顶寄存器,通过设置SS、SP的值可以创建栈,当使用push/pop命令时从栈顶进行操作。
    3.        DS数据段寄存器,当使用[X]读取内存时,会读取DS:X内存的内容
    4.   CS、IP寄存器,指令寄存器,当执行指令或者编写指令时,将指令写在CS段。
  3.   内存的存放方法
    1.   字在内存中存储时,要用两个地址连续的内存单元来存放。字的低位字节放在低地址单元,高位放在高地址单元。
    2.   DOS系统中地址0~9FFFF为主随机存储器,A0000~BFFFF为显存单元,C0000~FFFFF为只读存储器。
  4.   栈
    1.   栈在创建过程中会保留记录当时的CS、IP值和一些寄存器的状态,同时在对栈进行操作的过程中,机器会动态维护这些状态。
posted @ 2020-10-18 16:19  Lvatsit  阅读(177)  评论(2编辑  收藏  举报