更灵活的定位内存地址的方法
and 与 or 指令
and(逻辑与): 按位与,可以将某些位清零(与 0 相与):
asm
mov al, 01100011b
and al, 00111011b ; al = 00100011b(两者都是 1 的位保留)or(逻辑或): 按位或,可以将某些位置 1(与 1 相或):
asm
mov al, 01100011b
or al, 00111011b ; al = 01111011b(任意一方是 1 的位置 1)ASCII 码与字符处理
大写字母 A~Z 的 ASCII 码范围:41H~5AH(二进制第 5 位为 0) 小写字母 a~z 的 ASCII 码范围:61H~7AH(二进制第 5 位为 1)
大小写转换技巧:
asm
; 将 al 中的字母转换为大写(清除第 5 位)
and al, 11011111b
; 将 al 中的字母转换为小写(置 1 第 5 位)
or al, 00100000b实例: 将第一个字符串转大写,第二个转小写
asm
assume cs:codesg, ds:datasg
datasg segment
db 'BaSiC' ; 5 字节,偏移 0~4
db 'iNfOrMaTiOn' ; 11 字节,偏移 5~15
datasg ends
codesg segment
start:
mov ax, datasg
mov ds, ax
mov bx, 0
mov cx, 5
s: mov al, [bx]
and al, 11011111b ; 转大写
mov [bx], al
inc bx
loop s
mov bx, 5 ; 指向第二个字符串
mov cx, 11
s0: mov al, [bx]
or al, 00100000b ; 转小写
mov [bx], al
inc bx
loop s0
mov ax, 4c00h
int 21h
codesg ends
end start[bx+idata] 寻址
[bx+idata] 表示偏移地址为 (bx) + idata:
asm
mov ax, [bx+200] ; 等同写法:
mov ax, [200+bx]
mov ax, 200[bx]
mov ax, [bx].200利用 [bx+idata] 同时处理两个数组(C 风格对比):
c
// C 语言
char a[5] = "BaSiC";
char b[5] = "MinIX";
for (int i = 0; i < 5; i++) {
a[i] = a[i] & 0xDF; // 转大写
b[i] = b[i] | 0x20; // 转小写
}asm
; 汇编等价:a[i] → 0[bx],b[i] → 5[bx]
assume cs:codesg, ds:datasg
datasg segment
db 'BaSiC'
db 'MinIX'
datasg ends
codesg segment
start:
mov ax, datasg
mov ds, ax
mov bx, 0
mov cx, 5
s: mov al, [bx] ; a[i]
and al, 11011111b
mov [bx], al
mov al, 5[bx] ; b[i](偏移 5 个字节)
or al, 00100000b
mov 5[bx], al
inc bx
loop s
mov ax, 4c00h
int 21h
codesg ends
end startSI 和 DI 寄存器
SI(Source Index)和 DI(Destination Index)与 BX 功能相近,但不能拆分为 8 位寄存器使用。
常用于字符串操作(SI 指向源,DI 指向目标):
asm
; 将 'welcome to masm!' 复制到其后的 16 字节空间
assume cs:codesg, ds:datasg
datasg segment
db 'welcome to masm!'
db '................' ; 目标区域
datasg ends
codesg segment
start:
mov ax, datasg
mov ds, ax
mov si, 0 ; 源地址偏移
mov cx, 8 ; 一次复制 2 字节,共 8 次 = 16 字节
s: mov ax, 0[si] ; 读取源字符串中的字
mov 16[si], ax ; 写入目标区域
add si, 2
loop s
mov ax, 4c00h
int 21h
codesg ends
end start[bx+si] 和 [bx+di] 寻址
8086 CPU 中,[...] 内可用于寻址的寄存器只有 4 个:bx, si, di, bp。
合法的组合形式:
asm
mov ax, [bx]
mov ax, [bx+si]
mov ax, [bx+si+idata]
mov ax, [bx+di]
mov ax, [bx+di+idata]
mov ax, [bp]
mov ax, [bp+si]
mov ax, [bp+si+idata]
mov ax, [bp+di]
mov ax, [bp+di+idata]合法的配对:
bx+si,bx+di,bp+si,bp+di。不能bx+bp或si+di。
bp 的默认段寄存器是 SS(不是 DS):
asm
mov ax, [bp] ; 等同于 (ax) = ((ss)*16 + (bp))
mov ax, ds:[bp] ; 显式指定 ds,则用 ds