文章目录
5.4 Debug和汇编编译器Masm对指令的不同处理
我们在Debug中写过类似的指令:
mov ax,[0]
表示将ds:0处的数据送入al中
但是再汇编源程序中,"mov ax,[0]"指令被编译器当作"mov ax,0"处理
任务:将内存2000:0、2000:1、2000:2、2000:3单元中的数据传入al,bl,cl,dl中。
debug实现:
编译器实现:
总结:
- masm编译器中,[idata]被解释为idata。
- 可以用寄存器bx来实现,mov bx,1;mov bl,[bx]即可
- 还可以把段地址显式的表现出来,如mov bl,ds:[1]
5.5 loop和[bx]的联合应用
考虑一个问题:计算ffff:0-ffff:b单元中数据的和,结果存储在dx中。
(1)运算结果会不会超出dx的储存范围?
ffff:0~ffff:b是字节单元,范围为0~255,12个累加不会超出范围。
(2)能否将ffff:0~ffff:b中的数据直接累加到dx?
不行,因为ffff:0~ffff:b中的数据是8位的,不能直接累加到16位寄存器dx中。
(3)能否将ffff:0~ffff:b中的数据累加到dl,并将dh置为0?
不行,dl也是8位寄存器,累加可能造成进位丢失
解决方法:
mov al,ds:[0]
mov ah,0
add dx,ax
使用以上结构用ax作为中介进行累加
问题5.4 用loop指令实现上述程序
assume cs:code
code segment
mov ax,0ffffh
mov ds,ax
mov bx,0
mov dx,0
mov cx,12
s: mov al,[bx]
mov ah,0
add dx,ax
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
5.6 段前缀
指令"mov ax,[bx]"中,内存单元的偏移地址由bx给出,而段地址默认在ds中。这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的"ds:"、“cs:”、"ss:“或"es:”,在汇编语言中称为段前缀。
5.7 一段安全的空间
在8086模式中,随便向一段内存空间写入内容是很危险的,因为这段空间中可能存放着重要的系统数据或代码。
在一般的PC机中,DOS方式下,DOS和其他合法的程序一般都不会使用0:200~0:2FF的256个字节的空间。所以,我们使用这段空间是安全的。
5.8 段前缀的使用
任务:将ffff:0~ffff:b单元中的数据复制到0:200-0:20b单元中
assume cs:code
code segment
mov bx,0
mov cx,12
s: mov ax,0ffffh
mov ds,ax
mov dl,[ax] ;(dl)=((ds)*16+(bx)),将ffff:bx中的数据送入dl
mov ax,0020h
mov ds,ax ;每次循环设置两次ds,代码效率低下
mov [bx],dl
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
代码优化:
assume cs:code
code segment
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
mov ax,4c00h
int 21h
code ends
end