本章是前面章节的总结
1.处理的数据在哪?
2.数据有多长?
以下理由reg表示寄存器,sreg表示段寄存器
reg有:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di
sreg有:cs,ds,es,ss
8.1 bx,si,di 和 bp
1) [..]中只能使用这4种寄存器,其他的不可以
2) 只能有下列使用组合,其他的不可以
[bx],[bp],[si],[di],[bx+si],[bx+di],[bp+si],[bp+di] 可以+idata
3) 只要[...]中有bp,并且没给出段地址,段地址就在ss中
8.2 机器指令处理的数据在什么地方
可以在1)CPU中 2)内存中 3)端口中
实例:
mov ax,bx 数据bx在CPU中
mov bx,[0] 数据在内存中
mob ax,0 数据在CPU内部指令缓冲器
8.3 汇编语言中数据位置的表达
1)立即数:指令缓冲器
2)寄存器:CPU寄存器中
3)段地址SA+偏移地址EA:内存中, [bx]默认ds段寄存器,带bp的就是ss段寄存器,还可以手动指定 cs: ds: ss: es:
8.4 寻址方式
8.5指令要处理的数据有多长
1)寄存器操作由寄存器类型决定数据长度
mov ax,1 长度2字节
mov al,1 长度1字节
2)没有寄存器的指令 利用 ptr 指定长度
mov byte ptr ds:[bx],1 把1当做单字节放入ds:bx中
mov word ptr ds:[bx],1 把1当做一个字放入ds:bx和ds:bx+1中
3)其他的
push [0] pop [0] 栈操作都是按照字为单元的
8.6寻址方式的综合应用
实例:某公司82年信息如下名称:DEC 总裁:Ken Olsen 排名:137 收入:40 著名产品:PDP
这些数据在内存中位置如图所示 (从seg数据段的偏移地址60开始存放)
问题:88年公司的排名升至38,收入增加70,著名产品变为VAX 则如何改内存?
汇编 C
mov ax,seg struct company{char cn[3]; char hn[9]; int pm;
mov ds,ax int sr;char cp[3]}
mov bx,60H struct company dec={"DEC","Ken Olsen",137,40,"PDP"}
mov word ptr [bx].0CH,38 dec.pm = 38;
add word ptr [bx].0EH,70 dec.sr = dec.sr + 70
mov si,0 int i; i=0;
mov byte ptr [bx].10H[si],'V' dec.cp[i]='V';
inc si i++;
mov byte ptr [bx].10H[si],'A' dec.cp[i]='A'
inc si i++;
mov byte ptr [bx].10H[si],'X' dec.cp[i]='X'
总结:利用[bx].idata修改结构体中的一般变量
利用[bx].idata[si]修改结构体中的数组变量
8.7 DIV指令
除数有8位和16位,对应被除数16位和32位;
除数由寄存器(bl8,bx16)或者内存地址(单字节8,字单元16)给出,被除数由ax(16)或者((dx)*10000H+(ax))(32)给出;
8位除数时,AH存余数,AL存商。16位除数时,DX存余数,AX存商;
当除数是由内存地址给出时需要指定是byte还是word ptr
实例一:计算100001/100
易知:
除数100放在8位和16位寄存器/内存地址中都可以的;
被除数100001变成16进制=186A1H 一个AX不够存,所以DX放1,AX放86A1H;
DIV操作之后余数应该在DX中,商应该在AX中;
mov dx,1
mov ax,86A1H
mov bx,100
div bx
实例二:计算1001/100
易知:
除数100放在8位和16位寄存器/内存地址中都可以的;
被除数1001是可以放在16位中的,所以放在AX中;
DIV操作之后余数应该在AH中,商应该在AL中;
mov ax,1001
mob bl,100
div bl
8.8 伪指令dd
db,dw定义单字节1和字单元2,dd定义双字单元4
实例:计算第一个数除以第二个数,商放在第三个数中
assume cs:code,ds:data
data segment
dd 100001
dw 100
dw 1
data ends
code segment
start:
mov ax,data
mov ds,ax
mov dx,ds:[2] //100001高位放在dx中
mov ax,ds:[0] //100001低位放在dx中
div word ptr ds:[4]
mov ds:[6],ax
mov ax,4c00h
int 21h
code ends
end start
8.9 dup操作符
dup和db,dw,dd一样都是由编译器识别的,dup配合这三种伪指令使用,用于复制数据
db 重复次数 dup (字节型数据)
db 3 dup (0) => db 0,0,0
db 3 dup (1,2) => db 1,2,1,2,1,2
db 3 dup ('ab','AB') => db 'abABabABabAB'
dw 重复次数 dup (字型数据)
dd 重复次数 dup (双字型数据)
dup是非常有用的操作符,比如 定义N个字节的栈段就可以:
stack segment
db N dup (0)
stack ends