zoukankan      html  css  js  c++  java
  • 汇编语言-08数据处理的两个基本问题

    数据处理的两个基本问题

    定义的描述性符号: reg和sreg,reg表示一个寄存器,用sreg表示一个段寄存器。

    reg的集合包括:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、di;
    sreg的集合包括:ds、ss、cs、es。

    bx、si、di和bp

    在8086CPU中,只有这4个寄存器可以用在"[...]"中来进行内存单元的寻址。

     在[...]中,这4个寄存器可以单个出现,或只能以4种组合出现:bx和si、bx和di、bp和si、bp和di。比如:

    只要在[...]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中。比如:

    机器指令处理的数据在什么地方

    绝大部分机器指令都是进行数据处理的指令,处理大致可分为3 类:读取、写入、运算。在机器指令这一层来讲,并不关心数据的值是多少,而关心指令执行前一刻,它将要处理的数据所在的位置。指令在执行前,所要处理的数据可以在3个地方:CPU内部、内存、端口。

    汇编语言中数据位置的表达

    存取速度:寄存器 > 1级缓存 > 2级缓存 > 3级缓存 > 内存 > 硬盘。

    汇编语言中用3个概念来表达数据的位置。

    立即数(idata)

    对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中),在汇编语言中称为:立即数(idata),在汇编指令中直接给出。

    寄存器

    指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。

    段地址(SA)和偏移地址(EA)

    指令要处理的数据在内存中,在汇编指令中可用[X]的格式给出EA,SA在某个段寄存器中。

    ds段地址

    存放段地址的寄存器可以是默认的,使用常数、si、di和带有bx的组合时,段地址默认在ds,例如:

    ss段地址

    使用bp时,段地址默认在ss中,例如:

    显性给出段地址

    寻址方式

    当数据存放在内存中的时候,我们可以用多种方式来给定这个内存单元的偏移地址,这种定位内存单元的方法一般被称为寻址方式。

    段地址(Segment Address)

    偏移地址(Offset Address)也叫有效地址(EA,Effective Address)

    指令要处理的数据有多长

    可以处理两种尺寸的数据,byte和word。所以在机器指令中要指明,指令进行的是字操作还是字节操作。

    通过寄存器名指明要处理的数据的尺寸

    寄存器指明了指令进行的是字操作,例如:

     寄存器指明了指令进行的是字节操作,例如

    ptr指明内存单元的长度

    在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度, X在汇编指令中可以为word或byte。

    用word ptr指明了指令访问的内存单元是一个字单元,例如:

    用byte ptr指明了指令访问的内存单元是一个字节单元:

    在没有寄存器参与的内存单元访问指令中,用wordptr或byteptr显性地指明所要访问的内存单元的长度是很必要的。否则,CPU无法得知所要访问的单元是字单元,还是字节单元。

    byte ptr

    执行后查看结果

    word ptr

    用e命令修改ds:1000往后的16个字节数据为ff,然后用d查看

    查看刚才写的程序,找到要修改的地方,用a命令修改

    修改之后重新查看

    用r命令将ip指针重定向到1000:0,然后按t执行

    其他方法

    有些指令默认了访问的是字单元还是字节单元,比如,push[1000H]就不用指明访问的是字单元还是字节单元,因为push指令只进行字操作。

    寻址方式的综合应用

    内存中描述

    信息变更

    汇编实现

    C语言实现

    C语言对应的汇编

    div指令

    div是除法指令,使用div做除法的时候应注意以下问题:

    格式如下

    实例

    给出8位被除数,结果存放在同样8位的al和ah中。

    给出16位被除数,结果存放在同样16位的ax和dx中。

    dx高16位需要右移16位,即乘以2^16(十六进制为10000H),在加上低位的ax中存的值即计算出被除数。

    利用除法指令计算100001/100

    被除数100001大于65535,不能用ax寄存器存放,所以只能用dx和ax两个寄存器联合存放100001,也就是说要进行16位的除法。除数100小于255,可以在一个8位寄存器中存放,但是,因为被除数是32位的,除数应为16位,所以要用一个16位寄存器来存放除数100。

    100001的十六进制为186A1H,高十六位为1,低十六位为86A1。100的十六进制为64H。

    程序执行后,(ax)=03E8H(即1000),(dx)=1(余数为1)。

     

    利用除法指令计算1001/100

    被除数1001(3E9H)可用ax寄存器存放,除数100(64H)可用8位寄存器存放,也就是说,要进行8位的除法。

    程序执行后,(al)=0AH(即10),(ah)=1(余数为1)。

    伪指令dd

    前面我们用db和dw定义字节型数据和字型数据。dd是用来定义dword(double word,双字)型数据的。

    data segment
        db 1
        dw 1
        dd 1
    data ends

    在data段中定义了3个数据:
    第一个数据为01H,在data:0处,占1个字节;
    第二个数据为0001H,在data:l处,占1个字;
    第三个数据为00000001H,在data:3处,占2个字。

    用div计算data段中第一个数据除以第二个数据后的结果,商存在第三个数据的存储单元中。

    分析:

    dup

    dup(全称:duplicate)是一个操作符,在汇编语言中同db、dw、dd等一样,也是由编译器识别处理的符号。它是和db、dw、dd等数据定义伪指令配合使用的,用来进行数据的重复。

    使用格式

    例如: 

    db 3 dup (0)

    定义了3 个字节,它们的值都是0,相当千db 0,0,0 。

    db 3 dup (0,1,2)

    定义了9个字节,它们是0、l、2、0、1、2、0、1、2,相当千db 0,1,2,0,1,2,0,1,2。

    db 3 dup ('abc','ABC')

    定义了18个字节,它们是abcABCabcABCabcABC,相当千db ‘abcABCabcABCabcABC’。

    定义一个容量为200个字节的栈段

    不用dup

    用dw声明100个字,即开辟了200个字节的空间。

    stack segment
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    stack ends

    使用dup

    直接用db声明200个字节,内容为0。

    stack segment
        db 200 dup (0)
    stack ends
  • 相关阅读:
    python之字典dict
    python之 tuple元组
    python之列表list
    数字图像处理
    深度神经网络优化
    神经网络的前向后向及更新
    0220 kd树(鸢尾花分类)
    024 查看数据库的编码格式
    208 MySQL性能分析之Explain
    207 MySQL索引的数据结构B+树介绍
  • 原文地址:https://www.cnblogs.com/aeolian/p/12938171.html
Copyright © 2011-2022 走看看