第八章 数据处理的两个基本问题
(1)要处理的数据在什么地方?
(2)要处理的数据有多长?
定义描述性符号:reg–寄存器(ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di)
sreg–段寄存器(ds,es,ss,cs)
关于bx,si,di,bp:
在8086中只有这4个寄存器可以用在[…]中进行内存单元寻址。
在[…]中,这四个寄存器可以单个出现或者组合出现,组合形式只包括:bx+si、bx+di、bp+si、bp+di。
只要在[…]中使用bp,且未指明段地址,则默认为SS。
机器指令主要执行数据的处理,包括读取、写入和运算。在指令执行前,最重要的是需要知道待处理数据的位置。数据可以存在于三个地方:CPU内部、内存、端口。eg
mov ax,[0] 数据在内存,ds:0
mov ds,ax 数据在CPU内部,ax寄存器
mov ax,1 数据在CPU内部,指令缓冲器
表示数据的位置:
(1)立即数 idata:直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中)。eg
mov ax,1
add bx,2
mov al, ‘a’
(2)寄存器。eg
mov ds,ax
push bx
(3)段地址SA 和偏移地址EA。eg
mov ax, [0]
mov ax, [bx+si]
段地址默认在DS中。
mov ax, [bp+di+8]
段地址默认在SS中。
mov ax, es:[bx]
也可以给出段地址。
8086的指令应指明是字操作还是字节操作。
(1)通过寄存器名:
mov ax,1 字操作
inc ax 字操作
mov al,4 字节操作
mov al,bl 字节操作
(2)没有寄存器名时,使用 X ptr,X可以是word或者byte。
mov word ptr ds:[0],1 字操作
inc word ptr [bx] 字操作
inc byte ptr ds:[0] 字节操作
add byte ptr [bx],2 字节操作
(3)其他。默认操作单元的指令。
如push [1000h] 默认为字操作。
一般来说,我们可以用[bx+idata+si]的寻址方式访问结构体中的数据。用bx定位整个结构体,idata定位结构体中的某一数据项,si定位数组项中的每个元素。可以使用更贴切的书写方式:[bx].idata , [bx].idata[si]。
div除法指令:
(1)除数:有8位和16位,位于reg或者内存单元中。
(2)被除数:如果除数为8位,被除数则为16位,默认在ax中存放。
如果除数为16位,被除数则为32位,默认在dx和ax中存放,dx放高16位,ax放低16位。
(3)结果:如果除数为8位,al存放商,ah存放余数。
如果除数为16位,ax存放商,dx存放余数。
格式如下:
div reg 或者 div 内存单元
进行除法前,先分析被除数是不是大于65535,若大于则进行除数为16位的除法。如果被除数不大于65535,则分析除数是不是大于255,如果大于255,则进行除数为16位的除法。否则,进行除数为8位的除法。
伪指令dd define double word 4字节
datasg segment
dd 102020
datasg ends
dup操作符,由编译器识别处理,和数据定义伪指令(db,dd,dw)搭配使用,用来进行数据的重复。
db 3 dup (0) 相当于 db 0,0,0
db 3 dup (‘abc’,‘ABC’) 相当于 db ‘abcABCabcABCabcABC’
定义200字节的栈段:
stacksg segment
db 200 dup (0)
stacksg ends
实验7
定义字符串用db
assume cs:codesg,ss:stacksg,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
stacksg segment
dw 8 dup (0)
stacksg ends
codesg segment
start:
mov ax,data
mov es,ax
mov ax,stacksg
mov ss,ax
mov sp,16
mov ax,table
mov ds,ax
mov cx,21
mov bx,0
mov si,0
year:
push cx
mov cx,4
mov di,0
char:
mov al,es:[si]
mov [bx+di],al
inc si
inc di
loop char
add bx,16
pop cx
loop year
mov cx,21
mov bx,0
income:
mov ax,es:[si]
mov [bx+5],ax
add si,2
mov ax,es:[si]
mov [bx+7],ax
add si,2
add bx,16
loop income
mov cx,21
mov bx,0
staff:
mov ax,es:[si]
mov [bx+10],ax
add si,2
add bx,16
loop staff
mov cx,21
mov bx,0
aver:
mov ax,[bx+5]
mov dx,[bx+7]
div word ptr [bx+10]
mov [bx+13],ax
add bx,16
loop aver
mov ax,4c00h
int 21h
codesg ends
end start