1. 偏移地址的表示方式汇总:
1) 偏移地址表示规则:在中括号[ ]中最多有一个基址寄存器、最多有一个索引寄存器、最多有一个立即数,这三者的顺序可以任意,之间必须用+相连,不得用其它符号;
2) 基址寄存器:是指bx(base register基址寄存器)和bp(base pointer基址指针),两者都属于基址寄存器,只不过bx作为偏移地址时默认ds为段基,而bp作为偏移地址时默认ss作为段基;
3) 索引寄存器:是指si和di(Source/Destination Index Register),但它们也称为串操作变址寄存器;
串操作是指在两个数组之间进行数据传递,一个作为源数组(偏移地址用si表示)另一个作为目的数组(偏移地址用di表示),由于使用这两个寄存器作为偏移地址时CPU有特殊的指令实现串操作而使速率非常快,因此数组之间数据传递尽量使用这两个寄存器而不要使用其它寄存器作为偏移地址,这也是传操作变址寄存器名字的由来;
!注意:当偏移地址中不包含基址寄存器时一律将ds作为默认段基;
4) 立即数前缀表示法:比如10[bx]就等于[bx + 10],es:2FH[si + bx]就等于es:[bx + si + 2FH];
5) 多维数组表示法:可以将三个部分分别用三个中括号[ ]括起来,比如[10H][bp][si],三者顺序可以任意,[si][10H][bx]也行!
!注意:偏移地址中的立即数是对后缀敏感的,同样需要用后缀识别它是几进制的,进制问题在汇编代码中是全局的!
5) 举例:
ds默认前缀:
[si]
[di]
[si + 3]
[si][9]
[8][di]
[0FH + di]
[bx + di]
[di][3][bp]
[bx][si][30H]
[di + bx + 3]
[3 + si + bx]
3H[si + bx] == [si + bx + 3H]
[5]
ss默认前缀:
[bp]
[bp + si + 3]
[bp][3H][di]
7[si + bp]
**可以看见[ ]内顺序可以任意,如果使用段前缀表示法,比如ds:[bp + si + 9]则能精确确定是哪个段的内存单元了!
6) 一个使用bp、si、di的示例:
将第一行welcome to masm!挪到第二行的内存空间中
assume cs:codesg
codesg segment
db 'welcome to masm!'
db 16 dup('9')
start:
mov ax, codesg
mov ds, ax
mov ss, ax
mov bx, 0
mov si, 0
mov bp, 0
mov di, 16
mov cx, 16
lp:
mov al, [bx][si]
mov [bp][di], al
inc si
inc di
loop lp
mov ax, 4C00H
int 21H
codesg ends
end start
运行结果:
2. 示例:将每行的第一个字母变为大写(每行刚好16个字符):
assume cs:codesg, ss:datasg
datasg segment
db '1. file '
db '2. edit '
db '3. search '
db '4. view '
db '5. options '
db '6. help '
datasg ends
codesg segment
start:
mov ax, datasg
mov ss, ax
mov al, 11011111B
mov bp, 3
mov cx, 6
lp:
and [bp], al
add bp, 16
loop lp
mov ax, 4C00H
int 21H
codesg ends
end start