数据处理的两个基本问题
文章目录
1.bx、si、di和bp寄存器
- 在8086CPU中,只有这4个寄存器可以用在“[…]”中来进行内存单元的寻址
- 在[ ]中,这4个寄存器可以单个出现,或只能以4种组合出现:
bx和si、bx和di
、bp和si、bp和di
- 只要在[……]中使用寄存器bp,而指令中没有显性地给出段地址, 段地址就默认在ss中
;合法 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] ;特殊:使用bp寄存器,如果指令中没有显性给出段地址,段地址就默认在ss寄存器中 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)
2.机器指令处理的数据在什么地方
- 数据处理大致可分为3类:读取、写入、运算
- 在机器指令这一层来讲,并不关心数据的值是多少,而关心指令执行前一刻,它将要处理的数据所在的位置。指令在执行前,所要处理的数据可以在3个地方:CPU内部、内存、端口
3.汇编语言中数据位置的表达
汇编语言中用3个概念来表达数据的位置:立即数、寄存器、段地址(SA)和偏低地址(EA)
立即数
mov ax, 1 ;对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中) add bx, 2000h ;在汇编语言中称为:立即数(idata) or bx, 00010000b mov al, 'a'
寄存器
mov ax, bx ;指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。 mov ds, ax push bx mov ds:[0], bx push ds mov ss, ax mov sp, ax
段地址(SA)和偏低地址(EA)
;指令要处理的数据在内存中,在汇编指令中可用[X]的格式给出EA,SA在某个段寄存器中。 mov ax, [0] mov ax, [di] mov ax, [bx+8] mov ax, [bx+si] mov ax, [bx+si+8] ;以上段地址默认在ds中 mov ax, [bp] mov ax, [bp+8] mov ax, [bp+si] mov ax, [bp+si+8] ;以上段地址默认在ss中 mov ax, ds:[bp] mov ax, es:[bx] mov ax, ss:[bx+si] mov ax, cs:[bx+si+8] ;显式给出存放段地址的寄存器
4.寻址方式
5.指令要处理的数据有多长
8086CPU的指令,可以处理两种尺寸的数据,byte和word,处理情况如下:
注:
word ptr
表示指令访问的内存单元是两个字节单元,byte ptr
表示指令访问的内存单元式一个字节单元,这是强制定义为字大小
- 通过寄存器名指明要处理的数据的尺寸
- 例如:
mov al, ds:[0]
寄存器al指明了数据为1字节- 在没有寄存器名存在的情况下,用操作符
X ptr
指明内存单元的长度,X在汇编指令中可以为word
或byte
- 例如:
mov byte ptr ds:[0], 1
byte ptr 指明了指令访问的内存单元是一个字节单元- 有些指令默认了访问的是字单元还是字节单元
- 例如,
push [1000H]
,push 指令只进行字操作
6.寻址方式的综合应用
mov ax, seg
mov ds, ax
mov bx, 60h ;确定记录地址,ds:bx
;word ptr:指明访问的内存单元是两个字节单元
;byte ptr:指明访问的内存单元是一个字节单元
mov word ptr [bx+0CH], 38 ;排名字段改为38 [bx].0Ch
add word ptr [bx+0EH], 70 ;收入字段增加70 [bx].0Eh
mov si, 0 ;用si来定位产品字符串中的字符
mov byte ptr [bx+10H+si], 'V' ;[bx].10H[si]
inc si
mov byte ptr [bx+10H+si], 'A'
inc si
mov byte ptr [bx+10H+si], 'X'
C语言描述方式:
/*定义一个公司记录的结构体*/
struct company
{
char cn[3];/*公司名称*/
char hn[9];/*总裁姓名*/
int pm;/*排名*/
int sr;/*收入*/
char cp[3];/*著名产品*/
};
//sizeof (struct company) == 24
int main()
{
/*定义一个公司记录的变量,内存中将存有一条公司的记录*/
struct company dec = {"DEC", "Ken Olsen", 137, 40, "PDP"};
int i;
dec.pm = 38;
dec.sr = dec.sr + 70;
i = 0;
dec.cp[i] = 'V'; //mov byte ptr [bx].10h[si], 'V'
i++;
dec.cp[i] = 'A';
i++;
dec.cp[i] = 'X';
return 0;
}
7.div指令、伪指令dd、dup、mul指令
div是除法指令:
- 除数:有8位和16位两种,在一个
寄存器(reg)
或内存单元
中- 被除数:默认放在
AX
或DX
和AX
中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位- 结果:如果除数为8位,则
AL存储除法操作的商
,AH存储除法操作的余数
;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数;利用除法指令计算100001/100 ;100001D = 186A1H mov dx, 1 mov ax, 86A1H ;(dx)*10000H+(ax)=100001 mov bx, 100 div bx ;利用除法指令计算1001/100 mov ax, 1001 mov bl, 100 div b1
伪指令dd:
- db和dw定义字节型数据和字型数据
- dd是用来定义dword(double word,双字)型数据的伪指令
操作符dup指令:
- dup在汇编语言中同db、dw、dd等一样,也是由编译器识别处理的符号
- 它和db、dw、dd等数据定义伪指令配合使用,用来进行数据的重复
db 3 dup (0) ;定义了3个字节,它们的值都是0,相当于db 0,0,0。 db 3 dup (0, 1, 2) ;定义了9个字节,它们是0、1、2、0、1、2、0、1、2,相当于db 0,1,2,0,1,2,0,1,2。 db 3 dup ('abc', 'ABC') ;定义了18个字节,它们是abcABCabcABCabcABCC,相当于db 'abc', 'ABC' ,'abc' , 'ABC, 'abc', 'ABC'
mul指令:
- mul是乘法指令,使用 mul 做乘法的时候:相乘的两个数:要么都是8位,要么都是16位
- 8 位:
AL
中和8位寄存器
或内存字节单元
中- 16 位:
AX
中和16 位寄存器
或内存字单元
中- 结果:
- 8位:AX中
- 16位:DX(高位)和 AX(低位)中
- 格式:
mul 寄存器
或mul 内存单元
:;计算100*10 ;100和10小于255,可以做8位乘法 ;结果: (ax)=1000(03E8H) mov al,100 mov bl,10 mul bl ;8位cu