用[0]表示一个内存单元时,0表示偏移地址,段地址默认在ds中,单元的长度(类型)由具体指令中的其他对象指出
我们定义的描述性符号:“()”,表示一个寄存器或内存单元中的内容,比如
(ax)表示ax中的内容、(20000H)表示内存20000H单元的内容
(2000:0)、((ds):1000H)是不正确用法。
约定idata表示常量
汇编源程序中,数据不能以字母开头,在前面加0,比如0A000h
g命令:g 0012:使Debug从当前CS:IP指向的指令执行,直到(IP)=0012h为止
p命令:遇到loop指令时,用p命令,debug会自动重复循环,直到(cx)=0
1.[BX]
2.loop指令
格式:loop 标号
(1)(cx) = (cx) - 1
(2)判断cx中的值,不为零就转至标号处执行
cx中存放循环次数
4.debug和汇编编译器masm对指令的不同处理
debug将[idata]解释为一个内存单元,“idata”是内存单元的偏移地址,而编译器将“[idata]”解释为“idata”
怎样在源程序实现将2000:0中的数据送入al呢
(1)将偏移地址送入bx,用[bx]的方式访问内存单元
mov ax,2000h
mov ds,ax
mov bx,0
mov al,[bx]
这样比较麻烦
(2)在“[]”的前面显式地给出段地址所在的段寄存器
mov ax,2000h
mov ds,ax
mov al,ds:[0]
5.loop和[bx]的联合应用
要计算ffff:0~ffff:b单元中数据的和,结果存到dx:
(1)运算后的结果是否会超出dx所能存储的范围?
字节型数据,范围0~255,12个这样的数不会超过65535
(2)能直接累加到dx吗?
ffff:0~ffff:b中数据是8位的,不能直接累加到16位的dx
(3)能否将数据累加到dl中,并设置(dh)=0,从而实现累积到dx中?
向dl中累加12个8位数据,会进位丢失
(4)到底怎样?
用一个16位寄存器做中介,将内存单元中的8位数据赋值到一个16位寄存器ax,再将ax中的数据加到dx上,从而使运算对象类型匹配且结果不超界。
mov al,ds:[0]
mov ah,0
add dx,ax
如果表示内存单元偏移地址的X是个变量,就不能用常量表示偏移地址,将偏移地址放到bx中,每次循环bx+1
s: mov al,[bx]
mov ah,0
add dx,ax
inc bx
loop s
6.段前缀
mov ax,ds:[bx]
这些出现在访问内存单元的指令中,用于显示地指明内存单元的段地址的“ds:”,“cs:”,称为段前缀
7.一段安全的空间
dos方式下,一般0:200~0:2ff空间中没有系统或其他程序的数据或代码
8.段前缀的使用
要将内存ffff:0~ffff:b中的数据复制到0:200~0:20b单元中:
0:200~0:20b即0020:0~0020:b
assume cs:code
code segment
mov bx,0
mov cx,12
s: mov ax,0ffffh
mov ds,ax
mov dl,[bx]
mov ax,0020h
mov ds,ax
mov [bx],dl
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
因为源始单元ffff:X和目标单元0020:X相距大于64KB,在不同的64KB段里,每次循环要设置两次ds,效率不高
用两个段寄存器分别存放两单元的段地址,可省略循环中的设置程序段
mov ax,0ffffh
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx,12
s: mov dl,[bx]
mov es:[bx], dl
inc bx
loop s