汇编语言 第八章 数据处理的两个基本问题

  1. 处理的数据在什么地方?
  2. 要处理的数据有多长? ### 8.1 bx、si、di 和 bp

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #以下正确
    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,[dx]
    mov ax,[ds]
  4. […] 中,这 4 个寄存器可以单个出现,或只能以 4 种组合出现:bx 和 si、bx 和 di、bp 和 si、bp 和 di。比如下面的指令是正确的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #以下正确
    mov ax,[bx]
    mov ax,[si]
    mov ax,[di]
    mov ax,[bp]
    mov ax,[bx+si]
    mov ax,[bx+di]
    mov ax,[bp+si]
    mov ax,[bp+di]
    mov ax,[bx+si+idata]
    mov ax,[bx+di+idata]
    mov ax,[bx+si+idata]
    mov ax,[bx+di+idata]

    #以下错误
    mov ax,[bx+bp]
    mov ax,[si+di]
  5. 在要在 […] 中使用寄存器 bp,而指令中没有显性地给出段地址,段地址就默认在 ss 中。

    1
    2
    3
    4
    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 机器指令处理的数据在什么地方

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

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

    1. 立即数(idata)

      直接包含在机器指令中的数据(执行前在 CPU 的指令缓冲器中),在汇编指令中直接给出。

    2. 寄存器

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

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

      指令要处理的数据在内存中,汇编指令可用 [X] 的格式给出 EA在某个段寄存器中。存放段地址的寄存器可以是默认的,比如 ds、ss,也可以是显性给出的。

8.4 寻址方式

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

8086CPU 的指令,可以处理两种尺寸的数据,byte 和 word。所以在机器指令中要指明是何种操作。

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

    即区分 ax、bx、al、bl、ah、bh…

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #字单元
    mov word ptr ds:[0],1
    inc word ptr [bx]
    inc word ptr ds:[0]
    add word ptr [bx],2

    #字节单元
    mov byte ptr ds:[0],1
    inc byte ptr [bx]
    inc byte ptr ds:[0]
    add byte ptr [bx],2
  3. 其他方法

    有些指令默认了访问的是字单元还是字节单元。比如 push 指令只进行字操作。

8.6 寻址方式的综合应用

8.7 div 指令

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

  • 除数:有 8 位和 16 位两种,在一个 reg 或内存单元中。
  • 被除数:默认放在 AX 或 DX 和 AX 中,若除数为 8 位,被除数则为 16 位,默认放在 AX 中;若除数为 16 位,被除数则为 32 位,在 DX 和 AX 中存放,DX 存放高 16 位,AX 存放低 16 位。
  • 结果:如果除数为 8 位,则 AL 存储除法操作的商,AH 存储除法操作的余数;如果除数为 16 位,则 AX 存储除法操作的商,DX 存储除法操作的余数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
格式:
div reg
div 内存单元

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

div word ptr es:[0]
含义:(ax)=[(dx)*10000H+(ax)]/((es)*16+0)的商
(dx)=[(dx)*10000H+(ax)]/((es)*16+0)的余数

div byte ptr [bx+si+8]
含义:(al)=(ax)/((ds)*16+(bx)+(si)+8)的商
(ah)=(ax)/((ds)*16+(bx)+(si)+8)的余数

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

8.8 伪指令 dd

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

1
2
3
4
5
data  segment
db 1 01H,在 data:0 处,占 1 个字节;
dw 1 0001H,在 data:1 处,占 1 个字节;
dd 1 00000001H,在 data:3 处,占 2 个字节;
data ends

8.9 dup

dup 是一个操作符,用来配合使用 db、dw、dd 等数据定义伪指令来进行数据的重复。比如:

1
2
db 3 dup (0)      相当于 db 0,0,0
db 3 dup (0,1,2) 相当于 db 0,1,2,0,1,2,0,1,2

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×