实验4 [bx]和loop的使用

实验 [bx]loop的使用

1.编程:向内存0:200H~0:23fH依次传送数据0~633FH

程序分析:

1】内存0:200H~0:23fH空间与0020:0-0020:3f内存空间是一样的,(这个不会?ohMy God!,物理地址是唯一的,但逻辑地址组合是多种的。)

2】因为偏移地址是连续内存单元;我们可以把偏移地址做下文章。bx寄存器存储偏移地址(通过偏移地址的间接访问内存单元,这主要是写入的内存单元)。dx寄存器作为存储中间变量的容器(源数据,常量0-63)来向内存写入。

       汇编代码如下:

assume cs:code

code segment

    mov ax,0020H

    mov ds,ax   ;内存单元的段地址写入ds寄存器

    mov bx,0    ;bx寄存器存放偏移地址,初始化为0

    mov dx,0    ;dx寄存器存储常量数值0~63

    mov cx,40H  ;这里40H==64cx寄存器存放循环次数。也可以为64

   

s:  mov [bx],dx ;[bx]内存单元写入dx

    inc bx  ;累加bx

    inc dx  ;累加dx

    loop s

 

    mov ax,4c00H

    int 21H

code ends

end

 

2. 向内存0:200H~0:23fH依次传送数据0~633FH),9条命令的程序的简化版本(不包括伪代码):

程序分析:

1】内存0:200H~0:23fH空间与0020:0-0020:3f内存空间是一样的,(这个不会?ohMy God!,物理地址是唯一的,但逻辑地址组合是多种的。)为什么这样?数据0-6364个连续的数字,0-3fH也是连续的64个编号。我们可以使用一个bx变量就把偏移地址和数字的递增都搞定了!

修改后的汇编代码如下:

assume cs:code

code segment

    mov ax,0020H

    mov ds,ax   ;ds指向0020内存段

    mov bx,0    ;bx寄存器存放偏移地址,初始化为0,也当做源数据:常量数值

    mov cx,64   ;循环次数64

   

s:  mov [bx],bx ; [bx]内存单元写入bx数值

    inc bx

    loop s

 

    int 21H

code ends

end

实验体会:

1. bx寄存器一般用作偏移地址的存储,[bx]也就代表了段地址与[bx]组合后指向的内存单元。     为什么这样,还有一个原因就是在源程序中[xxxx]masm编译器中当做了常量xxxx,[bx]则没有这个问题,编译器当做是一个内存地址段的偏移地址。

2.cx寄存器在循环语句中,常作为计数器使用,loop循环语句把cx寄存器中的值作为判断是否循环的依据。

       CX寄存器在debug调试一个可执行程序时,CX的初始值为该程序的字节尺寸大小。

3.ds寄存器存放的是指向的内存单元的段地址。

4.debug模式下,注意源程序中loop s语句的体现,直接转移到了一个地址(偏移地址)了。

5.结束debug程序,键入q,退回到dos或命令提示符状态。

6.debug状态下,如果想要直接执行的到某个语句,可使用g命令,例如:

       g  XXXX(偏移地址)   在此之前的命令都执行了。

7.在汇编源程序中,数据不能以字母开头,前面可以加0,例如:0ff02H

8.debug下调试程序,遇到int 21H命令,键入p命令结束程序。

9.使用p命令可以结束loop的循环(当你遇到了loop语句的时候)。

10.在写汇编程序时,十进制和十六进制(用hH标注)可以混用。编译器自动给你转换了。

程序运行后结果:

-d ds:0

0020:0000  00 01 02 03 04 05 06 07-08 09 0A 0B 0C 0D 0E 0F   ................

0020:0010  10 11 12 13 14 15 16 17-18 19 1A 1B 1C 1D 1E 1F   ................

0020:0020  20 21 22 23 24 25 26 27-28 29 2A 2B 2C 2D 2E 2F    !"#$%&'()*+,-./

0020:0030  30 31 32 33 34 35 36 37-38 39 3A 3B 3C 3D 3E 3F   0123456789:;<=>?

3.下面程序的功能是将mov ax,4c00H之前的指令复制到内存0:200处,补全程序,上机调试,跟踪运行结果:

程序分析:

1】使用debug调试一个EXE文件时候,使用r命令查看寄存器状态,其中cx寄存器的值(初始值)就是该程序代码的大小(按照字节数)。我们可以通过运行debug程序来调试生成的EXE文件,前提你先将CX寄存器赋个值。

       侧面验证CX寄存器的另一个作用。

2cs段寄存器中存储的是指向程序代码段的段地址。此实验是将程序的代码(按字节)复制,故将cs寄存器中的指向代码的段地址赋值给ax,再通过ax寄存器赋值给ds段寄存器。(为什么不能支持从段寄存器cs直接赋值给段寄存器ds呢?回忆下,在8086CPU中,dssscses四个段寄存器存放的都是段地址,在CPU和我们来看。其他的寄存器一般存放的都是数据。

       4个段寄存器支持从其他寄存器中赋值,但不允许立即数直接赋值给段寄存器。)

3[bx]作为偏移地址为bx的内存单元,它支持的段地址默认是存储在ds段寄存器中的。       本例中ds[bx]指向的是存储代码段的内存单元(源内存段)。由于ds被占用了,故被写入的内存单元的段地址就没有存储的段寄存器了,es寄存器上场了,es存储了地址为0020H的段地址(目标内存段),那么同样使用[bx]偏移地址的话,必须明确的指出它的前缀,故es[bx]就指向了内存是0200H的内存单元地址段。

实验步骤如下:

1)首先使用debug调试该程序:假如这个可执行程序(经编译、连接无误后的)为test5.exe

debug  test5.exe  

2)使用r命令显示寄存器状态,显示整个程序代码所占字节数。

-r

AX=0000  BX=0000  CX=001C  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000

DS=0B55  ES=0B55  SS=0B65  CS=0B65  IP=0000   NV UP EI PL NZ NA PO NC

0B65:0000 8CC8          MOV     AX,CS

这里我们发现CX= 001CH

3)使用u命令显示汇编指令,求出需要复制的机器码字节数。

-u cs:0000

0B65:0000 8CC8          MOV     AX,CS

0B65:0002 8ED8          MOV     DS,AX

0B65:0004 B82000        MOV     AX,0020

0B65:0007 8EC0          MOV     ES,AX

0B65:0009 BB0000        MOV     BX,0000

0B65:000C B90300        MOV     CX,0003

0B65:000F 8A07          MOV     AL,[BX]

0B65:0011 26            ES:

0B65:0012 8807          MOV     [BX],AL

0B65:0014 43            INC     BX

0B65:0015 E2F8          LOOP    000F

0B65:0017 B8004C        MOV     AX,4C00

0B65:001A CD21          INT     21

       我们发现mov ax,4cooH/int 21H它们共占用了5个字节。所以在本实验中我们需要复制的代码字节数是001CH-0005H=0017H==23个字节,故cx计数寄存器赋值为2317H

4)完整的汇编代码如下:

assume cs:code

code segment

    mov ax,cs       ;cs段地址赋值给ax

    mov ds,ax       ;cs寄存器中的值初始化ds段寄存器,

   

    mov ax,0020H

    mov es,ax       ;es指向0020H内存段

     mov bx,0        ;偏移地址寄存器清零

    mov cx,17H      ;此处是循环次数:程序机器码的字节数,存储在CX

 

s:  mov al,[bx]     ;[bx]按照字节单元传送给al

    mov es:[bx],al  ;复制到es段内存中

    inc bx

    loop s

   

    mov ax,4c00H

    int 21H

code ends

end

实验结果测试:

-d 20:0

0020:0000  8C C8 8E D8 B8 20 00 8E-C0 BB 00 00 B9 17 00 8A   ..... ..........

0020:0010  07 26 88 07 43 E2 F8 00-00 00 00 00 00 00 00 00   .&..C...........

……

我们发现偏移地址从0000H~0017H存储了程序的执行代码。与程序执行代码存储的内存单元比较,我们发现一样的。

-d cs:0

0B65:0000  8C C8 8E D8 B8 20 00 8E-C0 BB 00 00 B9 17 00 8A   ..... ..........

0B65:0010  07 26 88 07 43 E2 F8 B8-00 4C CD 21 FF 06 48 91   .&..C....L.!..H.


  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值