本博文系列参考自<<汇编语言>>第三版,作者:王爽
计算机CPU进行数据处理包括两个基本的问题:1.数据在何处? 2.数据有多大? 本章作为一个前面内容的总结性章节,主要来说明这两个问题。我们定义两个符号reg和sreg。其中reg为寄存器,sreg为段寄存器
reg包括:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di
sreg包括:ds,ss,sp,es
8.1 bx、 si、 di和bp
1.在8086CPU只有bx,si,di以及bp这四个寄存器可以用在'[...]'中进行内存寻址:
比如下面的指令是正确的:
mov ax,[bx]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp]
mov ax,[bp+si]
mov ax,[bp+di]
下面的指令是不正确的:
mov ax,[cx]
mov ax,[ax]
mov ax,[dx]
mov ax,[ds]
比如下面的指令是正确的:
mov ax,[bx]
mov ax,[si]
mov ax,[di]
mov ax,[bp]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp+si]
mov ax,[bp+di]
mov ax,[bx+si+idata]
mov ax,[bx+di+idata]
mov ax,[bp+si+idata]
mov ax,[bp+di+idata]
mov ax,[bx+bp]
mov ax,[si+di]
比如如下指令:
mov ax,[bp] (ax)=((ss)*16+(bp))
mov ax,[bp+idata] (ax)=((ss)*16+(bp)+idata)
mov ax,[bp+si] (ax)=((ss)*16+(bp)+(si))
mov ax,[bp+si+idata] (ax)=((ss)*16+(bp)+(si)+idata)
下图说明了指令存储数据的位置:
8.3 汇编语言中数据位置的表达
(1)立即数:
直接包涵在汇编指令中的数据称为立即数(执行前在CPU中的指令缓冲区)
例如: mov ax,1
add bx,2000h
(2)寄存器
执行指令所需要的数据在寄存器中:
比如: mov ax,bx
push bx
(3)段地址和偏移地址
指令要处理的数据在内存中则需要段地址加偏移地址进行寻址
段地址可以是默认给出的(默认ds):
比如:mov ax,[0](默认段地址ds)
mov ax,[di](默认段地址ds)
mov ax,[bp](默认段地址ss)
mov ax,[bp+si](默认段地址ss)
也可以显示给出段地址:
比如:mov ax,ds:[0]
mov ax,ds:[bp]
8.4 寻址方式
当数据存储在内存的时候,我们有多种方法可以求得其偏移地址,求得偏移地址的方法称为寻址方式。下图为所有的寻址方式的总结。
8.5 指令要处理的数据有多长
如何指定要处理的数据有多大有如下方式:
1.通过寄存器指明要处理数据的大小
比如字操作: mov ax,ds:[0]
比如字节操作: mov al,ds:[0]
2.在没有寄存器的情况下,可以使用X ptr指明需要处理数据大小。X可以为word或byte
比如字操作: mov word ptr ds:[0],1
比如字节操作: mov byte ptr ds:[0],1
3.有些指令默认访问数据大小
比如 push 指令
push [1000H]默认进行字操作
8.6寻址方式的综合应用
假设一个公司的的数据存放在seg:60h为起始地址的内存区域,如下:
现在要个将137改为38,将40改为70,将'PDP'改为'VAX'
我们可以通过[bx+si+idata]方式来寻址,同时用X PTR指定要更改数据的长度。所以核心程序如下:
8.7 div指令
div指令的注意事项如下:
1.除数:有8位和16位两种,在一个reg和内存单元中。
2.被除数:默认放在AX或DX和AX中,如果除数为8位,则被除数为16位,默认在AX中存放;如果除数为16位,则被除数为32位,在DX和AX中存放,DX存放高16位,AX存放地16位
3.结果:如果除数为8位,则AL存储商,AH存储余数。如果除数为16位,则AX存储商,DX存储余数。
格式如下:
div reg
div 内存单元
比如:
div byte ptr ds:[0]
含义:(al)=(ax)/((ds)*16+0)的商 (ah)=(ax)/((ds)*16+0)的余数
div word ptr [bx+si+8]
含义:
(ax)=[(dx)*10000h+(ax)]/((ds)*16+(bx)+(si)+8)的商
(dx)=[(dx)*10000h+(ax)]/((ds)*16+(bx)+(si)+8)的商
8.8伪指令dd
dw,db,dd
其中dw为定义一个字空间,db为定义一个字节空间,dd为定义一个双字的空间
8.9 dup
dup也是一个伪指令,是由编译器识别的。往往dup配合着dw,db,dd使用进行数据的重复。
比如:
db 3 dup (0)
定义了三个字节,它们的值都为0,相当于 db 0,0,0
db 3 dup (0,1,2)
定义了九个字节,它们的值为0,1,2,0,1,2,0,1,2相当于 db 0,1,2,0,1,2,0,1,2