zoukankan      html  css  js  c++  java
  • [BX]和loop指令

    1.[bx]表示内存的用法,loop指令的用法

     

    语法格式

    loop 标号

    通常我们用loop指令来实现循环功能,cx中存放循环次数。

    cpu执行指令过程

    1.cx=cx-1

    2.判断cx的值是否为0

    如果cx不等于0,跳转到标号出执行

    如果cx=0,执行loop后面的其它指令。

    2.综合应用loop和[BX]编程时,对于类型不一致(8位,16位)、数据超出范围等情形的处理(结合5.3节程序5.3和5.5节实例)

     在汇编程序中,数据不能以字母开头。例:A000h在汇编程序中要写为:0A000h

    从ds中可以得到PSP的段地址SA,PSP的偏移地址为0,则物理地址为SA*16+0,可用段地址和偏移地址表示为:SA+10h:0

    遇到loop指令时,可以用p指令执行,debug自动重复执行循环代码,直到(cx)=0,也可以用g命令来达到目的。

    类型不一致时,例:ffff:6单元中是一个字节单元,ax是一个16位寄存器,数据长度不一样,如何赋值?

    我们说的是“赋值”,就是说,让ax中的数据的值(数据的大小)和ffff:0006单元中的数据的值(数据的大小)相等。8位数据01h和16位数据0001h的数据长度不一样,但它们的值是相等的。那么我们如何赋值,设ffff:0006单元中的数据是xxh,若要ax中的值和ffff:0006单元中的相等,ax中的数据应为00xxh。所以,若实现ffff:0006单元向ax赋值,应该令(ah)=0,(al)=(ffff6h)。

    有两个问题:类型的匹配和结界的不超界。具体的说,就是在做加法的时候,我们有两种方法:

    1.(dx)=(dx)+内存中的8位数据;

    2.(dl)=(dl)+内存中的8位数据。

    第一种方法中的问题是两个运算对象的类型不匹配,第二种方法中的问题是结果有可能超界。解决这两个看似矛盾的问题,目前的方法就是得用一个16位寄存器来做中介,将内存单元中的8位数据赋值到一个16位寄存器ax中,再将ax中的数据加到dx上,从而使两个运算对象的类型匹配并且结果不会超界。

    assume cs:code
    code segment
    
             mov ax,0ffffh
             mov ds,ax
             mov bx,0   ;初始化ds:bx指向ffff:0
    
             mov dx,0   ;初始化累加寄存器dx,(dx)=0
    
             mov cx,12  ;初始化循环计数寄存器cx,(cx)=12
    
    
         s:  mov al,[bx]
             mov ah,0
             add dx,ax    ; 间接向dx中加上((ds)*16+(bx))单元的数值
             inc bx       ; ds:bx指向下一个单元
    loop s mov ax,4c00h
    int 21h code ends end

    3.debug工具中t命令、p命令、g命令用法

     t命令

    单步执行;遇loop会进入循环内部继续单步执行;遇int会进入中断程序内继续单步执行;

    p命令

    单步执行;遇loop或int会当作整体执行,不进入内部单步执行;

    g命令

    执行到指定地址;或遇程序结束或int,则终止执行。

    4.debug和masm在处理内存单元上的不同及问题处理方式

     在debug中编程实现

    mov ax,2000
    mov ds,ax
    mov al,[0]
    mov bl,[1]
    mov cl,[2]
    mov dl,[3]

    汇编源程序实现

    assume cs:code
    code segment
    
    mov ax,2000h
    mov ds,ax
    mov al,[0]
    mov bl,[1]
    mov cl,[2]
    mov dl,[3]
    
    mov ax,4c00h
    int 21h
    
    code ends
    end

     

    可以看出,debug和编译器masm对形如“mov ax,[0]”这类指令在解释上的不同,debug和编译器对这些指令中的“[idata]”有不同的解释。debug将它解释为“[idata]”是一个内存单元,“idata”是内存单元的偏移地址;而编译器将“[idata]"解释为“idata”。

    那么解决方法是,可将偏移地址送入bx寄存器,用[bx]的方式来访问内存单元。比如我们可以这样访问2000:0单元。

    mov ax,2000h
    mov ds,ax     ;段地址2000h送入ds
    mov bx,0      ;偏移地址0送入bx
    mov al,[bx]   ;ds:bx单元中的数据送入al
  • 相关阅读:
    封装图片处理类(缩略图)
    封装表单验证类
    魔术方法
    封装自己的smartyBC类
    快捷键
    unicode
    基本数据类型课上练习
    数制总结
    12.29.作业
    12.28作业
  • 原文地址:https://www.cnblogs.com/byxy/p/10054217.html
Copyright © 2011-2022 走看看