• [汇编语言]-第五章[bx]和loop指令


    1- [bx]和内存单元的描述 [0]表示内存单元, 他的偏移地址为0

      mov ax,[0] 将一个内存单元的内容送入到ax.这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为0,段地址在ds中.

      mov al,[0] 将一个内存单元的内容送入到al,这个内存单元的长度为1字节(字节单元),存放一个字节,偏移地址为0,段地址在ds中.

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

      mov ax,[bx] 将一个内存单元的内容送入到ax, 这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ds中.

      mov al,[bx] 将一个内存单元的内容送入到al, 这个内存单元的长度为1字节(字节单元),存放一个字,偏移地址在bx中,段地址在ds中.

    2- 我们定义得描述性符号"()" 表示一个寄存器或一个内存单元中得内容.

      (ax) 表示ax中得内容,(al)表示al中得内容

      (20000H)表示内存20000H单元的内容,()中的内存单元的地址为物理地址

      (ds)*16+(bx)

        ()中的元素可以有三种类型

        1>寄存器名 (ax)

        2>段寄存器名(ds)

        3>内存单元的物理地址(一个20位数据) (20000H) ,((ds)*16+(bx))

          不正确的表示(1000H), (2000:0),((ds):1000H)

    3- 约定符号idata表示常量

      mov ax,[idata]就代表mov ax,[1] mov ax,[2] mov ax,[3]等

      mov bx,idata 就代表 mov bx,1  mov bx,2  mov bx,3等

    4- loop

      实现2^12 (N * 2 可以用N + N实现)

     1 assume cs:code
     2 code segment
     3      mov ax, 2
     4      mov cx, 11
     5  s: add ax, ax
     6      loop s    ;(1) (cx) = (cx) -  1; (2)判断(cx)不为零则转到s所标示的地址处执行.如为0则执行下一条指令
     7      
     8      mov ax, 4c00H
     9      int 21h
    10 code ends
    11 end

    计算ffff:0006单元中的数乘以3,结果存储在dx中.

     1 assume cs:code
     2 code segment
     3     mov ax, 0ffffH ;大于9FFFH的十六进制数据,A000H,B000H,FFFEH,FFFFH在书写时是以字母开头的,而在汇编程序中, 数据不能以字母开头.所以要在前面加0,如0FFFE
     4     mov ds, ax
     5     mov bx, 6H
     6     
     7     mov al, [bx]
     8     mov ah, 0
     9     
    10     mov dx, 0
    11     
    12     mov cx, 3
    13 s:add dx, ax
    14     loop sa
    15     
    16     mov ax, 4c00H
    17     int 21H
    18 code ends
    19 end
    20     

     分析

    (1) 运算后的结果是否会超出dx所能存储的范围

      ffff:0006存储的是一个字节型的数据,范围0-255之间,则用它乘以3结果不会大于65535,可以在dx中放下

    (2) 我们循环累加实现乘法, 用哪个寄存器进行累加

      我们将ffff:0006单元中的数据赋值给ax, 用dx进行累加.先设(dx) = 0 ,然后做3次 (dx) = (dx) + (ax).

    (3) ffff:6是一个字节单元,ax是一个16位寄存器,数据长度不一样,如何赋值?

      赋值:是要求ffff:0006单元中得数据,与ax中得数据值相等. 如 8位数据 06H 和 16位的 0006H 的数据长度不一样,但是值是相等的.

      (al) = (ffff6H)

      (ah) = 0

    5- Debug和汇编编译器Masm对指令的不同处理

      Debug指令:

      mov ax,[0] 将ds:0处的数据送入ax中

      

      汇编编译器指令:

      mov ax,[0] 被编译器当做指令 mov ax,0   

     1 assume cs:code
     2 code segment
     3     mov ax,1000
     4     mov ds,ax
     5     mov ax,[0]
     6     
     7     mov ax,4c00H
     8     int 21h
     9 code ends
    10 end

      

    那么如何实现内存2000:0, 2000:1, 2000:2, 2000:3单元中得数据,送入al, bl, cl, dl中?

    (1) 目前的方法是将偏移地址送入bx寄存器中,用[bx]方式访问内存单元. 访问 2000:0内存单元

    mov ax,2000H

    mov ds,ax

    mov bx,0

    mov al,[bx]

    (2) 这样做是可以,但是比较麻烦,希望像debug中[]访问内存.只需要在"[]"前面显示的给出段地址所在的寄存器.

    mov ax,2000H

    mov ds,ax,

    mov al,ds:[0]

    比较下汇编程序中以下指令的含义:

    mov ax,[0]    (ax) = 0

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

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

    mov al,ds:[bx]      (al) = ( (ds) *16 + (bx) ) 与 mov al,[bx]相同

    6- loop和[bx]的联合应用

    计算ffff:0-ffff:b单元中的数据和,结果存储到dx中.

    分析:

    (1) 运算后的结果是否超出dx的范围

      ffff:0-ffff:b单元中得范围为0-255 12个这样的数相加不能超过65535,可以在dx中存放下

    (2) 是否将ffff:0-ffff:b中得数据直接累加到dx中

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

    (3) 能否将ffff:0-ffff:b中得数据累加到dl中, 并设置(dl)=0, 从而实现累加到dx中.

      不行,因为dl是8位寄存器,能容纳的数据范围0-255,ffff:0-ffff:b中得数据也是8位,如果向dl中累加12个8位的数据,很可能造成进位丢失

    (4)到底怎样才能将ffff:0-ffff:b中的8位数据,累加到16位寄存器dx中

      在做累加时有两种方法

      (dx) = (dx) + 内存中得8位数据  //运算对象的类型不匹配

      (dl) = (dl) + 内存中得8位数据    //结果有可能超界

      我们用16位的寄存器来做中介,将内存中8位数据,赋值到一个16位的寄存器ax中, 再将ax中得数据累加到dx中.从而使两运算对象的类型匹配并且结果不会超界

      

       

  • 相关阅读:
    【HBase】三、HBase和RDBMS的比较
    【HBase】二、HBase实现原理及系统架构
    【HBase】一、分布式数据库HBase简介
    【LeetCode】9、Palindrome Number(回文数)
    【LeetCode】7、Reverse Integer(整数反转)
    【HDFS】四、HDFS的java接口
    【HDFS】三、HDFS命令行接口
    【HDFS】二、HDFS文件读写流程
    【HDFS】一、HDFS简介及基本概念
    【Redis】四、Redis设计原理及相关问题
  • 原文地址:https://www.cnblogs.com/galoishelley/p/3543120.html
Copyright © 2020-2023  润新知