《汇编语言(第四版)》---王爽 第八章数据处理的两个基本问题 详细笔记+代码 ~后续章节笔记,课后检测,实验代码持续更新中

《汇编语言(第四版)》—王爽 第八章数据处理的两个基本问题

第八章数据处理的两个基本问题

引言

计算机是进行数据处理、运算的机器,那么就有两个基本的问题:

  • 处理的数据在什么地方
  • 要处理的数据有多长

对于这两个问题,在机器指令中必须给出明确或者隐含的说明,否则计算机将无法工作

本章中我们就要针对8086CPU进行这两个问题的讨论。

为了使得描述更加的简洁,我们定义的描述性符号:reg(寄存器)和sreg(段寄存器)

reg的集合包括:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di

sreg的集合包括:ds,ss,cs,es(扩展段)

8.1、bx、si、di、bp

1> 在8086CPU中只有这四个寄存器(bx、si、di、bp)可以用在[…]中进行内存地址的寻址

正确的表示形式:

  • mov ax,[bx]
  • mov ax,[bx+si]
  • mov ax,[bx+di]
  • mov ax,[bp]
  • mov ax,[bp+si]
  • mov ax,[bp+di]

错误的表示形式:

  • mov ax,[cx]
  • mov ax,[ax]
  • mov ax,[ds]

2> 在[…]中,这四个寄存器可以单独出现,或者只能以四种组合形式出现

  • bx和si
  • bx和di
  • bp和si
  • bp和di

错误的用法:

  • mov ax,[bx+bp]
  • mov ax,[si+di]

3> 只要在[…]中使用寄存器bp,而指令中没有显性的给出段地址,段地址就默认在ss中

  • mov ax, [bp]
    含义: (ax)= ( (ss)*16+(bp) )
  • mov ax, [bp+idata]
    含义:(ax)= ( (ss)*16+(bp)+idata)
  • mov ax , [bp+si]
    含义:(ax)= ( (ss)*16+(bp)+(si) )
  • mov ax,[bp+si+idata]
    含义: (ax)= ( (ss)*16+(bp)+(si)+idata)

8.2、机器指令处理的数据所在的位置

绝大多数的机器指令都是进行数据的处理的指令,处理大致分为三类:读取,写入,运算

机器指令并不关心数据的值是多少,而关心指令执行前一刻,它将要处理的数据在什么位置

指令执行前,所要处理的内存可以在三个地方:CPU内部,内存,端口

在这里插入图片描述

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

在汇编语言中如何表示数据的位置?

  • 立即数(idata)
    • 对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中)
  • 寄存器
    • 指令要处理的数据在寄存器中
  • 段地址(SA)和偏移地址(EA)
    • 指令要处理的数据在内存中
    • 存放段地址的寄存器可以是默认的
      • mov ax,[bx] 段地址默认在ds中
      • mov ax,[bx+si+idata] 段地址默认在ds中
      • mov ax,[bp+si+idata] 段地址默认在ss中
    • 存放段地址的寄存器也可以显性的给出
      • mov ax,ds:[bp] 含义:(ax) = ((ds) * 16 + (bp))
      • mov ax,es:[bx] 含义:(ax) = ((es) * 16 + (bx))
      • mov ax,cs:[bx+si+idata] 含义:(ax)=((cs)*16+(bx)+(si)+idata)

8.4、寻址方式

定位内存地址的方法一般被称为寻址方式

在这里插入图片描述
直接寻址:

在这里插入图片描述
寄存器间接寻址

在这里插入图片描述
寄存器相对寻址:

在这里插入图片描述
在这里插入图片描述
基址变址寻址:

在这里插入图片描述
在这里插入图片描述
相对基址变址寻址:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

8.5、指令要处理的数据有多长

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

确定指令要处理的数据有多长的方法:

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

    • 字操作
      在这里插入图片描述
    • 字节操作
      在这里插入图片描述
  • 在没有寄存器名存在的时候,用操作符X ptr 指明内存单元的长度,X在汇编指令中可以为word或者byte

    • word ptr
      在这里插入图片描述
    • byte ptr
      在这里插入图片描述
  • 其他方法

    • 有些指令默认了访问的单元是字单元还是字节单元、
    • 例如:push 因为push只进行字操作 sp = sp - 2

8.6、寻址方式的综合应用

通过例子来进一步的探讨各种寻址的作用

在这里插入图片描述
在这里插入图片描述

mov ax,seg
mov ds,ax
mov bx,60h                 ;确定记录地址ds:bx

mov word ptr [bx+0ch],38   ;排名字段改为38
add word ptr [bx+0eh],70   ;收入字段增加70
mov si,0                   ;si来定位产品字符串中的字符
mov byte ptr [bx+10h+si],'v'
inc si
mov byte ptr [bx+10h+si],'A'
inc si
mov byte ptr [bx+10h+si],'x'

我们可以看出,8086CPU提供的如[bx+si+idata]的寻址方法为结构化的处理提供了方便

从上面可以看到,一个结构化的数据包含了多个数据项,而数据项的类型又不相同,有的是字型数据,有的是字节型数据,有的是数组(字符串)。

一般来说,我们用[bx+si+idata]的方式来访问结构体中的数据,用bx定位整个结构体,用idata定位结构体中的某一个数据项,用si定位数组项中的每个元素。为此,汇编语言提供了更为贴切的书写方式,如:[bx].idata、[bx].idata[si]。

8.7、div指令

div是除法指令,使用div做除法的时候:

  • 除数:8位或者16位,在寄存器的内存单元中
  • 被除数:默认放在AX或者是DX和AX中

除数和被除数的关系

除数 被除数

8位 16位(AX)

16位 32位(DX和AX)

结果存放:

运算 8位 16位

商 AL AX

余数 AH DX

div指令格式

  • div reg(寄存器)

  • div 内存单元

div指令的示例

  • div byte ptr ds:[0] 含义如下

    • (al) = (ax)/((ds)*16+0)的商
    • (ah) = (ax)/((ds)*16+0)的余数
  • div word ptr ds:[0] 含义如下

    • (ax) = [(dx)*10000H + (ax)]/ ((ds) * 16+0)的商
    • (dx) = [(dx)*10000H + (ax)] / ((ds) *16+0)的余数
  • div byte ptr [bx+si+8]

    • (al)=(ax)/((ds) * 16 +(bx)+(si)+8)的商
    • (ah)=(ax)/((ds) * 16 +(bx)+(si)+8)的余数
  • div word ptr [bx+si+8 ]

    • (ax)=[ (dx) * 10000H+(ax) ] / ( (ds)*16+(bx)+(si)+8)的商
    • (dx)= [ (dx) * 10000H+(ax)] / ((ds)*16+(bx)+(si)+8)的余数

编程实现除法指令计算 100001/100

分析:被除数100001的值大于了65535,所以不能用ax存放,只能用ax和dx联合起来存放

除数100小于255,可以在一个8位的寄存器中存放,但是由于被除数是32位则此时除数应该为16位,所以用一个16位的寄存器存放除数100

因为要分别将dx和ax赋100001的高16位和低16位,所以应该先将100001表示为16进制形式:186A1H

mov bx,1
mov ax,86A1H
mov bx,100
div bx

编程实现除法指令计算1001/100

分析:被除数1001小于65535,因此可以用ax进行存放,除数可以用8位的寄存器存放

mov ax,1001
mov bl,100
div bl

8.8、伪指令dd

之前学过的db定义的字节型数据,dw定义的字型数据

dd是用来定义dword(double word双字)型数据的

示例:datasg segment

​ db 1

​ dw 1

​ dd 1

​ datasg ends

在datasg段中定义的三个数据:

第一个数据:01H 在datasg:0处,占一个字节空间

第二个数据:0001H 在datasg:1处,占一个字型空间

第三个数据:00000001H 在datasg:3处,占一个双字型空间

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

data segment
	dd 100001
	dw 100
	dw 0
data ends

分析:data 段中的第一个数据是被除数,为 dword(双字)型,32位,所以在做除法之前,用dx 和 ax存储。应将data:0字单元中的低16位存储在ax 中,data:2字单元中的高16位存储在dx中。程序如下。

mov ax,data
mov ds,ax
mov ax,ds:[0]   ;ds:0字单元中的低16位存储在ax中
mov dx,ds:[2]	;ds :2字单元中的高16位存储在dx中
div word ptr ds:[4] ;用dx :ax中的32位数据除以ds :4字单元中的数据
mov ds:[6],ax   ;将商存储在ds:6字单元中

8.9、dup

dup是一个操作符,由编译语言中同db,dw,dd等一样,也是由编译器进行识别处理的符号

它是和db,dw,dd等数据定义的伪指令配合使用,用来进行数据的重复

dup示例
  • db 3 dup(0) 定义了三个字节,它们的值都是0 相当于db 0,0,0

  • db 3 dup(0,1,2) 定义了九个字节,它们是0,1,2,0,1,2,0,1,2

  • db 3 dup(‘abc’,'ABC) 定义了18个字节 它们是a,b,c,A,B,C,a,b,c,A,B,C,a,b,c,A,B,C

dup的使用格式
  • db 重复的次数 dup(重复的字节型数据)
  • dw 重复的次数 dup(重复的字型数据)
  • dd 重复的次数 dup(重复的双字型数据)

dup是一个非常有用的操作符

例如定义一个容量为200个字节的栈段时,不使用dup

在这里插入图片描述
如果使用dup则为:

stack segment
	db 200 dup(0)
stack ends

猜你喜欢

转载自blog.csdn.net/weixin_60363168/article/details/127030610