and 和 or 指令

将 al 和操作数进行按位与。

1
2
mov al, 01100011b
and al, 00111011b

将 al 和操作数进行按位或。

1
2
mov al, 01100011b
or al, 00111011b

以字符的形式给出数据

1
2
db 'unIX'
db 'foRK'

相当于

1
2
db 75h, 6eh, 49h, 58h
db 66h, 6fh, 52h, 4bh
1
mov al, 'a'

相当于

1
mov al, 61h

[bx+idata]

[bx+idata] 表示一个内存单元,它的偏移地址为 (bx) + idata

将一个内存单元的内容送入 ax,内存单元长度为一个字,偏移地址为 bx 中的数值加上 200,段地址在 ds 中。

1
mov ax, [bx+200]

字符串大小写转换问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
assume cs:codesg, ds:datasg

datasg segment
db 'BaSiC'
db 'MinIX'
datasg ends

codesg segment
start:
mov ax, datasg
mov ds, ax ;数据段地址指向 datasg
mov bx, 0
mov cx, 5 ;循环 5 次
s:
mov al, [bx] ;把 [bx] 内存单元放入 al
and al, 11011111b ;转成大写
mov [bx], al ;数据写回 [bx]
mov al, 5[bx] ;把 [5+bx] 内存单元放入 al
or al, 00100000b ;转成小写
mov 5[bx], al ;数据写回 [5+bx]
inc bx ;偏移量增加 1
loop s
mov ax, 4c00h
int 21h
codesg ends
end start

SI 和 DI

si、di 与 bx 功能相近,但 si、di 不能分成两个 8 位寄存器使用。

以下三组指令实现相同的功能:

1
2
mov bx, 0
mov ax, [bx]
1
2
mov si, 0
mov ax, [si]
1
2
mov di, 0
mov ax, [di]

以下三组指令实现相同的功能:

1
2
mov bx, 0
mov ax, [bx+123]
1
2
mov si, 0
mov ax, [si+123]
1
2
mov di, 0
mov ax, [di+123]

利用 si、di 复制数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
assume cs:code,ds:data
data segment
db 'welcome to masm!'
db '0000000000000000'
data ends

code segment
start:
mov ax, data
mov ds, ax
mov si, 0
mov di, 16
mov cx, 8
s:
mov ax, [si]
mov [di], ax
add si, 2
add di, 2
loop s
mov ax, 4c00h
int 21h
code ends
end start

[bx+si] 和 [bx+di]

[bx+si] 表示一个内存单元,它的偏移地址为 (bx) + (si),即 bx 中的数值加上 si 中的数值。

将一个内存单元的内容送入 ax,这个内存单元的长度为 2 字节,存放一个字,偏移地址为 bx 中的数值加上 si 中的数值,段地址在 ds 中。

1
mov ax, [bx+si]

也可以写作:

1
mov ax, [bx][si]

[bx+si+idata] 和 [bx+di+idata]

将一个内存单元的内容送入 ax,这个内存单元的长度为 2 字节,存放一个字,偏移地址为 bx 中的数值加上 si 中的数值再加上 idata,段地址在 ds 中。

1
2
3
4
5
mov ax, [bx+200+si]
mov ax, [200+bx+si]
mov ax, 200[bx][si]
mov ax, [bx].200[si]
mov ax, [bx][si].200

不同寻址方式的灵活应用

寻址方式总结:

  1. [idata] 用一个常量表示地址,直接定位一个内存单元
  2. [bx] 用一个变量表示地址,间接定位一个内存单元
  3. [bx+idata] 用一个变量和一个常量表示地址,在一个起始地址的基础上用一个变量间接定位一个内存单元
  4. [bx+si] 用两个变量表示地址
  5. [bx+si+idata] 用两个变量和一个常量表示地址

利用栈暂存 cx 计数器来处理双重循环问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
assume cs:code,ds:data,ss:stack

data segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
data ends

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

code segment
start:
mov ax, stack
mov ss, ax
mov sp, 16
mov ax, data
mov ds, ax
mov bx, 0
mov cx, 4
s0:
push cx ;将外层循环的 cx 计数器的值压栈
mov si, 0
mov cx, 3
s:
mov al, [bx+si]
and al, 11011111b
mov [bx+si], al
inc si
loop s
add bx, 16
pop cx
loop s0
mov ax, 4c00h
int 21h
code ends
end start