本人微信公众号"aeolian"~

汇编语言-08数据处理的两个基本问题

数据处理的两个基本问题

《汇编语言-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个寄存器可以用在”[…]”中来进行内存单元的寻址。

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

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

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

《汇编语言-08数据处理的两个基本问题》

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

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

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

立即数(idata)

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

《汇编语言-08数据处理的两个基本问题》

寄存器

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

《汇编语言-08数据处理的两个基本问题》

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

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

ds段地址

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

《汇编语言-08数据处理的两个基本问题》

ss段地址

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

《汇编语言-08数据处理的两个基本问题》

显性给出段地址

《汇编语言-08数据处理的两个基本问题》

寻址方式

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

段地址(Segment Address)

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

《汇编语言-08数据处理的两个基本问题》

指令要处理的数据有多长

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

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

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

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

ptr指明内存单元的长度

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

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

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

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

byte ptr

《汇编语言-08数据处理的两个基本问题》

执行后查看结果

《汇编语言-08数据处理的两个基本问题》

word ptr

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

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

修改之后重新查看

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

其他方法

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

寻址方式的综合应用

《汇编语言-08数据处理的两个基本问题》

内存中描述

 

《汇编语言-08数据处理的两个基本问题》

信息变更

《汇编语言-08数据处理的两个基本问题》

汇编实现

《汇编语言-08数据处理的两个基本问题》

C语言实现

《汇编语言-08数据处理的两个基本问题》

C语言对应的汇编

《汇编语言-08数据处理的两个基本问题》

 

《汇编语言-08数据处理的两个基本问题》

div指令

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

《汇编语言-08数据处理的两个基本问题》

格式如下

《汇编语言-08数据处理的两个基本问题》

实例

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

《汇编语言-08数据处理的两个基本问题》

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

《汇编语言-08数据处理的两个基本问题》

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。

《汇编语言-08数据处理的两个基本问题》

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

 《汇编语言-08数据处理的两个基本问题》

利用除法指令计算1001/100

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

《汇编语言-08数据处理的两个基本问题》

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

《汇编语言-08数据处理的两个基本问题》

伪指令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段中第一个数据除以第二个数据后的结果,商存在第三个数据的存储单元中。

《汇编语言-08数据处理的两个基本问题》

分析:

《汇编语言-08数据处理的两个基本问题》

dup

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

使用格式

《汇编语言-08数据处理的两个基本问题》

 

例如: 

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

 

点赞

Leave a Reply

Your email address will not be published. Required fields are marked *