• 汇编语言(学习笔记-----[bx]和loop)


    1、[bx]是什么??

        和[0]有些类似,[0]表示内存单元,它的偏移地址是0

         [bx]同样也表示一个内存单元,它的偏移地址在bx中,mov ax,[bx]  (字)   mov  al,[bx]  (字节)

        mov ax,[bx]功能

        bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中

    2、描述一个内存单元,需要两种信息:1>内存单元的地址;2>内存单元的长度(类型)

         我们用[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中,单元的长度(类型)可以由具体指令中的其他操作对象指出

    3、loop:英文循环

        用一个描述性的符号“()”来表示一个寄存器或一个内存单元中的内容

        看一下(X)应用,比如:

        1>ax中的内容为0010H,我们可以这样来描述:(ax)=0010H;

        2>2000:1000处的内容为0010H,(21000H)=0010H;

        3>对于mov ax,[2]的功能,我们可以这样来描述:(ax)=((ds)*16+2);

        4>对于add ax,2的功能,我们可以这样来描述:(ax)=(ax)+2;

    4、约定符号idata表示常量:

        mov  ax,[idata]就代表mov ax,[1]、mov ax,[2]、…

        mov ax,idata就代表mov ax,1、mov ax,2…

        mov ds,idata就代表 mov ds,1、mov ds,2…是非法指令

    5、loop指令格式:loop 标号,CPU执行loop指令的时候,要进行两步操作:

            >1<  (cx)=(cx)-1。

            >2<  判断cx中的值,不为零则转至标号出执行程序,如果为零则向下执行。

            >3< cx中的值影响着loop指令的执行结果

            >4< loop指令来实现循环功能,cx中存放循环次数

            >5<loop指令中的标号所表示地址要在前面

            >6<框架如下:mov cx,循环次数

                               s:

                                   循环执行的程序段

                                   loop s

            >7< 在汇编语言程序中,数据不能以字母开头,所以要在前面加  0

    6、loop和[bx]的联合应用:

    一、    计算ffff:0~ffff:b内存单元的数据的和,结果存储在dx中

           1、运算后的结果是否会超出dx(16位)所在存储的范围??

                ffff:0~ffff:b内存单元(8位)中的数据是字节型数据,范围在0~255(2^8)之间,12个这样的数据相加,结果不会大于65535(2^16),可以在dx中存放

             2、是否将ffff:0~ffff:b中的数据直接累加到dx中??

                    当然不行,因为ffff:0~ffff:b中的数据是8位,不能直接加到16位的寄存器dx中。

             3、能否将ffff:0~ffff:b中的数据累加到dl中,并设置(dh=0,从而实现累加到dx中的目标?)

                    这也不行,因为dl是8位寄存器,能容纳的数据的范围在小255之间,ffff:0~ffff:b中德数据也是8位,如果仅向dl中累加12个8位数据,可能造成进位丢失

             4、到底怎样将用ffff:0~ffff:b中的8位数据,累加到16位寄存器dx中?

                  从上面的分析中,我们可以看到,这里面有个问题,类型的匹配(8位和16位)和结果的不超界

                  具体的说,就是在做加法的时候我们有两种方法:

                       (dx)=(dx)+内存中的8位数据;(类型不匹配)

                       (dl)=(dl)+内存中的8位数据;(可能越界)

            5、就是用一个16位的寄存器做中介

                  我们将内存单元中8位数据赋值到一个16位寄存器ax中,再将ax中的数据加到dx中上,从而使两个运算对象的类

                     型对象的类型匹配并且结果不会超界

    assume cs:codesg
    codesg segment
    start:
        mov ax,0ffffh
        mov ds,ax
        mov bx,0
        
        mov dx,0
        mov cx,12 
      s:
        mov al,[bx]
        mov ah,0
        add dx,ax
        inc bx
        loop s
        
        mov ax,4c00H
        int 21H
      codesg ends
    end start

    7、指令分辨:(MASM编译器解释)

        mov al,[0]            (al)=0

        mov al,ds:[0]       (al)=((ds)*16+0)

        mov al,[bx]          (al)=((ds)*16+bx)

        mov al,ds:[bx]      同上


    8、一段安全的空间

         在8086CPU模式中,随意向一段内存空间写入内容是很危险的,因为这段空间中可能存放着重要的系统数据或代码

         在一般的PC机中,DOs方式下,dos和其他合法的程序一般都不会使用0:200~0:2FF(0:200H~0:2FFH)的256个字节的空间,所以,我们使用这段空间是安全的。

         考虑一个问题:

          将内存ffff:0~ffff:b段元中的数据拷贝到0:200~020b单元中。

          分析一下:

          (1)0:200~020b单元等同于0020:0~0020:b单元,它们描述的是同一段内存空间

          (2)拷贝的过程应用循环实现,简要描述如下:初始化:X=0;循环12次:将FFFF:X单元中德数据送入0020:X

          (3)在循环中,原单元FFFF:X和目标单元的0020:X的偏移地址是X变量,我们用bx来存放X变量

          (4)用0:200~020b单元等同于0020:0~0020:b单元,它们描述的是同一段内存空间,就是为了使目标单元的偏移地址和原始单元的偏移地址从同一数值0开始。

  • 相关阅读:
    8、泛型程序设计与c++标准模板库5.函数对象
    Linux和Windows系统分区原理
    Linux命令----cd
    为什么会产生TCP/IP?
    区间 dp
    dp-划分数 (递推)
    dp-LCS(递归输出最短合串)
    dp-(LCS 基因匹配)
    位运算符
    求对数
  • 原文地址:https://www.cnblogs.com/haoyuanyuan/p/3231847.html
Copyright © 2020-2023  润新知