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

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

一、实验目的
1. 熟练掌握使用debug工具编写和调试x86汇编命令的方法
2. 掌握8086CPU、寄存器、内存的基础知识
3. 理解并掌握内存中多字节数据的存放:小端法
4. 理解并掌握「栈」内存空间的特性和使用
5. 掌握指令mov, add, sub, jmp, push, pop的基础用法

二、实验内容
  1. 教材实验1(P35)
  2. 教材实验2(P71)

三、实验结论
  1. 教材实验1结论,教材实验1中「2. 实验任务」(P45)

实验任务(1)
  机器码数据较多,只用前4行实验。

  ①、a命令

    使用a命令输入指令,修改cs:ip所指地址,修改之后使用t命令单步调试,结果如图:

  

   ②、e命令:

    输入机器码之后也需要注意cs:ip是否指向当前机器码存储地址,修改后同样使用t命令单步调试,

    结果如图:

   

  使用a命令输入汇编指令/e命令输入机器码对应的寄存器值变化:

机器码 汇编指令 寄存器变化   
b8   20   4e mov ax,4e20H ax = 4e20H
05   16   14 add ax,1416H ax = 6236H
bb    00   20 mov bx,2000H bx = 2000H
01    d8 add ax,bx ax = 8236H

 

 

 

 

   

 

 

 


实验任务(2)

   使用a命令将指令输入到命令来窗口中,并修改cs:ip的值,

   

   使用命令t单步调试,结果如图:

  

  继续使用t单步执行,执行到2的8次方,结如图:

  

  这三行汇编代码实现的是计算2的n次方,结果存放在寄存器ax中,由汇编指令jmp 2000:0003实现跳转,

  执行之后跳转回20003,该地址段存储指令(add ax,ax),以此循环实现计算2的n次方,并将值存储在ax上。

 

实验任务(3)

  使用d命令从段地址fff00,偏移量为0开始查找,在偏移量为f0的内存单元中存在字符02/27/20

  结果如图:

  

  更改该行数据,改变日期,将日期改为12/06/20(数字0~9 对应的ASCII码值 30~39)

  

  以上均在虚拟机win7系统中的doc命令窗口使用debug进行实验,

  使用docbox查找到日期为:01/01/20,同时在docbox中无法修改该段地址中的数据,结果如下:

  

  尝试使用e命令修改该段数据,再次查看时发现该段数据未发生改变。


实验任务(4)

  使用e命令修改指定地址内的数据,如图:

  

  按下回车之后可以贯彻到命令窗口上出现图标,改变地址:-e b820:0000 34 56 78 5d 4f 34 21 09,

  结果如图:

  

  改变值:-e b820:0000 01 01 02  02 03 03 04 04,

  结果如图:

  

 在修改数据之后命令窗口上会立即做出响应出现特殊图标,说明修改的该段地址是显存地址。对于8080cpu而言,

 地址A000H~BFFFFH的8KB空间为显存地址空间。cpu向该段内存地址输入数据,数据将会被写入显存中,然后会被显卡输出到显示器上。

 

2. 教材实验2结论
教材实验2中「2. 实验任务」(P74)
实验任务(1)

  ① 截图记录:使用 e 命令修改 内存单元0022:0~0022:f 中的数据,及修改后查看是否正确写入的操作
  ② 截图记录:使用 a 命令输入的 p74 指令
  ③ 截图记录:每一行指令单步调试(如单步调试步骤多,可分屏截图,但不要有遗漏)
  ④ P74 中指令执行后各个寄存器填空结果,以在文档中手工标注或手机拍照截图方式复制在文档中。

        对于③单步调试的观察,与理论上分析的结果进行比较,检验是否一致。如不一致,分析原因。

  在使用 a 命令输入指令调试之前,先使用 e 命令将内存单元 0022:0 ~0022:7连续 8 个字节数据修改为 50H, 51H, 52H, 53H, 54H, 55H, 56H, 57H
  将 P74 实验任务(1)中第1行的 mov ax, ffff → 改为 mov ax, 0022。

  修改内存单元数据,如图:

  

  使用a命令输入指令,如图:

  

  使用t命令单步执行,如图:

   

   中间调试步骤省略......

   

    执行指令对应的寄存器之变化如下:

    mov ax,0022
    mov ds,ax


    mov ax,2200
    mov ss,ax


    mov sp,0100
    mov ax, [0]      ;ax=5150
    add ax, [2]       ;ax=A4A2
    mov bx, [4]      ;bx=5554
    add bx, [6]       ;bx=ACAA


    push ax          ;sp=00FE;    修改的内存单元的地址是:220FE 内容为:A4A2
    push bx          ;sp=00FC;  修改的内存单元的地址是:220FC 内容为:ACAA
    pop ax            ;sp=00FE;  ax=ACAA
    pop bx            ;sp=0010;  bx=A4A2


    push [4]         ;sp=00FE;  修改的内存单元的地址是:220FE 内容为:5554
    push [6]         ;sp=00FC;  修改的内存单元的地址是:220FC 内容为:5756

    实验结果于理论结果相同

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

   观察其中寄存器sp的值的变化,使用push命令执行入栈操作,sp值(段地址偏移量)减2;在执行pop命令执行出栈操作,sp(段地址偏移量)值加2。

      在使用t命令单步执行时,发现mov sp,0100在mov ss,ax后直接执行了,再使用t命令执行的是mov ax,[0]

 

实验任务(2)
  ① 截图记录图 3.19 中使用 a命令输入的 7 行指令,使用 e 命令修改 2000:0~2000:f 的值,及修改后查看的部分
  ② 单步调试每一行汇编指令的截图。每一条指令单步调试后,都使用 d 命令查看2000:0~2000:f 的值。

    观察每一条指令执行后相关寄存器值的变化,及 2000:0~2000:f 单元值的变化,并思考原因。  

  以文字方式陈述:
    ① 前3行汇编指令的功能,特别是,mov sp, 10意味着什么?初始时栈顶和栈底分别是?

    ② 基于单步调试观察到的变化,给出你对此的思考及可能原因分析。

  使用a命令输入指令,使用t命令单步调试,并用d命令查看2000:0~2000:f 的值的变化

  

  

  ① 前3行汇编指令的功能,特别是,mov sp, 10意味着什么?初始时栈顶和栈底分别是?

    mov ax,2000     将值2200存入寄存ax

    mov ss,ax   是将寄存器ax'的值存入到阶段地址寄存器ss中

    mov sp,10  是移动指针指向该段地址的偏移量为0010的内存空间

    ax,ss,sp均为寄存器,ss为段地址寄存器,ss:sp指向栈顶元素(可以理解为指针),mov sp, 10意味着将栈顶指针移到内存地址为20010的内存单元;

    初始时栈顶ss:sp为2000:0010,栈底ss:sp为:2000:0010(栈底地址错误:应为2000:000E)
  ② 基于单步调试观察到的变化,给出你对此的思考及可能原因分析。

  发现:栈在使用push指令存入数据之前在执行mov指令后栈中的数据就会发生改变,在执行栈相关操作之前会将寄存器存

     储的值存储到栈中指定位置上(如图),随着栈相关操作的进行,数据会存入栈中,先前存放寄存器的值的地址将会被占用,用来存放入栈的值。

  

 

四、实验总结

1、mov指令:寄存器使用mov赋值,注意段地址寄存器不可以使用mov 传入立即数来更改段地址,应使先将立即数存

       入寄存器中, 再使用mov存入段地址寄存器。(mov 段地址寄存器 , 寄存器)

   段地址寄存器:ss,cs,ds  注意:ip(指令指针寄存器)不能直接传值;同时mov指令的两个操作数不能同时

          为内存单元(两个内存单元之间不能直接存值)

   add指令:add指令对的操作数不能同时为内存单元.

2、8086PC机内存地址空间分配:00000~9FFFF为主存储器地址空间

                A0000~BFFFF现存地址空间

               C0000~FFFFF为给类ROM地址空间

3、栈:一个栈段的容量最大为64KB(2^16),在使用栈时,栈的段地址ss的值不会变,改变的时寄存器sp的值sp最

    大的移动范围(0~FFFFH)限制栈的容量为64KB

   ss:sp理解为栈顶指针,使用push指令和pop指令时寄存器sp的变化:

    使用push命令时:寄存器sp向减2,再将值存入内存单元中;使用pop指令时,先取出值,再将寄存器sp加2

    使用push指令存入值,使用pop指令取值之后栈内存单元中存的值任然存在,不会因为pop指令的执行而清除。

  查看栈对应的段地址内存单元中的数据可以发现:入栈的数据数值高位存放在地址的高位,数值的低位存放在地址的低位(采用的是小端法)

posted @ 2020-10-15 21:24  3个月亮  阅读(325)  评论(3)    收藏  举报