第五章 [BX]和loop指令
2014年2月19日 星期三 15时50分39秒
1. [bx]和内存单元的描述
mov ax,[0]
mov al,[0]
用[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中,单元的长度类型可以由具体指令中的其他操作对象(寄存器等)指出。
[bx]同样也表示一个内存单元,它的偏移地址在bx中,例如:
mov ax,[bx]
将一个内存单元送入ax,这个内存单元的长度为2个字节(1个字),偏移地址在bx中,段地址在ds中。
2 loop
[bx]和loop指令的应用
3 我们定义描述性的符号“()”
用“()”来表示一个寄存器或一个内存单元的内容。
4 约定符号 idata 表示常量
我们用“idata”表示常量
例如: mov ax,[idata]就代表,mov ax,1 mov ax,2 等等。
mov bx,idata 就代表, mov bx,1 mov bx,2 等等
mov ds,idata是非法的。(不能直接将数值赋给ds寄存器)
5.1 [bx]
mov ax,[bx] (ax)=((ds)*16+(bx))
mov [bx],ax ((ds)*16+(bx))=(ax)
5.2 Loop指令
Loop指令的格式: loop 标号
用cx和loop指令配合实现循环功能的程序如下:
assume cs:code
code segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov 4c00H
int 21H
code ends
end
5.3 在Debug中跟踪用Loop指令实现的循环程序
计算ffff:0006单元中的数乘以123,结果存储在dx中。
assume cs:code
code segment
mov ax,0ffffH
mov ds,ax
mov bx,6
mov al,[bx]
mov ah,0
mov dx,0
mov cx,123
s: add dx,ax
loop s
mov ax,4c00H
int 21H
code ends
end
5.4 Debug和汇编编译器masm对指令的不同处理
将内存中2000:0,2000:1,2000:2,2000:3 单元中的数据送入al,bl,cl,dl中
(1)Debug中的实现:
-u 147D:0017
147D:0017 8ED8 MOV DS,AX
147D:0019 A00000 MOV AL,[0000]
147D:001C 8A1E0100 MOV BL,[0001]
147D:0020 8A0E0200 MOV CL,[0002]
147D:0024 8A160300 MOV DL,[0003]
(2)masm中的实现:
-u 147D:0000
147D:0000 B80020 MOV AX,2000
147D:0003 8ED8 MOV DS,AX
147D:0005 B000 MOV AL,00
147D:0007 B301 MOV BL,01
147D:0009 B102 MOV CL,02
147D:000B B203 MOV DL,03
147D:000D B8004C MOV AX,4C00
147D:0010 CD21 INT 21
可以在Debug中和源程序中写入同样的指令“mov al,[0]”,“mov bl,[1]”,“mov cl,[2]”,“mov dl,[3]”, Debug将“[idata]”解释为一个内存单元,而编译器将"[idata]"解释为idata。
那么在源程序中,如何将内存中的数据"2000:0","2000:1"等的数据送入到al,bl,cl中呢?
目前的方法是经偏移地址送如到bx寄存器中,用[bx]的方法来访问内存单元。 如
mov ax,2000
mov ds,ax
mov bx,0
mov al,[bx]
以上这种做法比较麻烦。
还可以在"[]"之前显式的给出段地址所在的段寄存器。例如:
mov ax,2000
mov ds,ax
mov al,ds:[0]
mov bl,ds:[1]
5.5 loop和[bx]的联合应用
计算offffH:0--offffH:b的值:
assume cs:code
code segment
mov ax,0ffffH
mov ds,ax
mov dx,0
mov bx,0
mov cx,0bH
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中。我们可以在访问内存的指令中显示第给出内存单元的段地址所在的段寄存器。比如:
mov ax,ds:[bx]
其中ds称为段前缀。
5.7 一段安全的空间
在8086模式中,随意向一段内存中写入内容是危险的。
如果我们需要向内存空间中写入数据的话,要使用操作系统给我们分配的空间。而不应该直接使用地址任意指定内存单元。
在一般PC机中,DOS方式下,Dos和其他合法的程序一般都不会使用 0:200--0:2ff(00200f---002ffh)这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,[bx]
; mov ax,0020H
; mov ds,ax
; mov [bx],dl
; loop s
; mov ax,4c00H
; int 21H
; code ends
; end
//使用两个段寄存器(ds,ex)分别存放原始单元和目标单元。
assume cs:code1
code1 segment
mov bx,0
mov cx,12
mov ax,0020H
mov ex,ax
mov ax,0ffffH
mov ds,ax
s: mov dl,[bx]
mov ex:[bx],dl
inc bx
loop s
mov ax,4c00H
int 21H
code1 ends
end
实验4 [bx]和loop的使用
2014-3-4 23:05 记 @jushannongchang.haidianqu.beijing
2014年2月19日 星期三 15时50分39秒
1. [bx]和内存单元的描述
mov ax,[0]
mov al,[0]
用[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中,单元的长度类型可以由具体指令中的其他操作对象(寄存器等)指出。
[bx]同样也表示一个内存单元,它的偏移地址在bx中,例如:
mov ax,[bx]
将一个内存单元送入ax,这个内存单元的长度为2个字节(1个字),偏移地址在bx中,段地址在ds中。
2 loop
[bx]和loop指令的应用
3 我们定义描述性的符号“()”
用“()”来表示一个寄存器或一个内存单元的内容。
4 约定符号 idata 表示常量
我们用“idata”表示常量
例如: mov ax,[idata]就代表,mov ax,1 mov ax,2 等等。
mov bx,idata 就代表, mov bx,1 mov bx,2 等等
mov ds,idata是非法的。(不能直接将数值赋给ds寄存器)
5.1 [bx]
mov ax,[bx] (ax)=((ds)*16+(bx))
mov [bx],ax ((ds)*16+(bx))=(ax)
5.2 Loop指令
Loop指令的格式: loop 标号
用cx和loop指令配合实现循环功能的程序如下:
assume cs:code
code segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov 4c00H
int 21H
code ends
end
5.3 在Debug中跟踪用Loop指令实现的循环程序
计算ffff:0006单元中的数乘以123,结果存储在dx中。
assume cs:code
code segment
mov ax,0ffffH
mov ds,ax
mov bx,6
mov al,[bx]
mov ah,0
mov dx,0
mov cx,123
s: add dx,ax
loop s
mov ax,4c00H
int 21H
code ends
end
5.4 Debug和汇编编译器masm对指令的不同处理
将内存中2000:0,2000:1,2000:2,2000:3 单元中的数据送入al,bl,cl,dl中
(1)Debug中的实现:
-u 147D:0017
147D:0017 8ED8 MOV DS,AX
147D:0019 A00000 MOV AL,[0000]
147D:001C 8A1E0100 MOV BL,[0001]
147D:0020 8A0E0200 MOV CL,[0002]
147D:0024 8A160300 MOV DL,[0003]
(2)masm中的实现:
-u 147D:0000
147D:0000 B80020 MOV AX,2000
147D:0003 8ED8 MOV DS,AX
147D:0005 B000 MOV AL,00
147D:0007 B301 MOV BL,01
147D:0009 B102 MOV CL,02
147D:000B B203 MOV DL,03
147D:000D B8004C MOV AX,4C00
147D:0010 CD21 INT 21
可以在Debug中和源程序中写入同样的指令“mov al,[0]”,“mov bl,[1]”,“mov cl,[2]”,“mov dl,[3]”, Debug将“[idata]”解释为一个内存单元,而编译器将"[idata]"解释为idata。
那么在源程序中,如何将内存中的数据"2000:0","2000:1"等的数据送入到al,bl,cl中呢?
目前的方法是经偏移地址送如到bx寄存器中,用[bx]的方法来访问内存单元。 如
mov ax,2000
mov ds,ax
mov bx,0
mov al,[bx]
以上这种做法比较麻烦。
还可以在"[]"之前显式的给出段地址所在的段寄存器。例如:
mov ax,2000
mov ds,ax
mov al,ds:[0]
mov bl,ds:[1]
5.5 loop和[bx]的联合应用
计算offffH:0--offffH:b的值:
assume cs:code
code segment
mov ax,0ffffH
mov ds,ax
mov dx,0
mov bx,0
mov cx,0bH
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中。我们可以在访问内存的指令中显示第给出内存单元的段地址所在的段寄存器。比如:
mov ax,ds:[bx]
其中ds称为段前缀。
5.7 一段安全的空间
在8086模式中,随意向一段内存中写入内容是危险的。
如果我们需要向内存空间中写入数据的话,要使用操作系统给我们分配的空间。而不应该直接使用地址任意指定内存单元。
在一般PC机中,DOS方式下,Dos和其他合法的程序一般都不会使用 0:200--0:2ff(00200f---002ffh)这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,[bx]
; mov ax,0020H
; mov ds,ax
; mov [bx],dl
; loop s
; mov ax,4c00H
; int 21H
; code ends
; end
//使用两个段寄存器(ds,ex)分别存放原始单元和目标单元。
assume cs:code1
code1 segment
mov bx,0
mov cx,12
mov ax,0020H
mov ex,ax
mov ax,0ffffH
mov ds,ax
s: mov dl,[bx]
mov ex:[bx],dl
inc bx
loop s
mov ax,4c00H
int 21H
code1 ends
end
实验4 [bx]和loop的使用
2014-3-4 23:05 记 @jushannongchang.haidianqu.beijing