第八章 数据处理的两个基本问题
一、寄存器
*reg:表示寄存器。8086寄存器包括ax,bx,cx,dx,al,ah,bl,bh,cl,ch,dl,dh,ss,cs,es,ds,sp,bp,si,di;
其中sreg表示段寄存器,包括ds,es,ss,cs.
*只有bx,bp,si,di这四个寄存器可用来作为偏移地址寻址。且bx和bp不能同时使用,si和di不能同时使用,具体应用方式如下:
[bx],[bp],[si],[di];[bx+si],[bx+di],[bp+si],[bp+di];[bx+si+idata],[bp+di+idata]..etc.
*对于使用bx寻址的应用,段地址默认存在ds中;对于bp寻址,默认段地址在ss中。
二、指定内存单元长度的方式:相对于对寄存器的操作,寄存器如ax-bx-cx等等,均为字操作,al-ch-dl均为字节操作;对于立即数的操作须指定内存单元长度。如:mov word ptr [0ah],1的操作对象为[0ah]和[0bh]两个内存单元,表示向ds:[0ah]中存入1,向ds:[0ah]中存入0.如:mov byte ptr [0a],1的操作对象为[0ah]一个内存单元,表示向ds:[0ah]中存入1。
三、汇编语言中数据的存放有三种情况:
1、立即数(idata):是指直接包含在指令中的数据,存放在CPU的指令缓冲器中;
2、存放在寄存器中。
3、存放在内存中。
四、关于Dec公司的记录修改问题。
初始数据在内存单元中的分布如下:
段地址为reg,Dec公司数据存储的起始地址为reg:[60h].
A reg:[60h+0h]~reg:[60h+2h] ;DEC ;3byte
B reg:[60h+3h]~reg:[60h+0bh]&mdash ;Ken Oslen ;9byte
C reg:[60h+0ch]~reg:[60h+0dh]&mdash ;137 ;1 word
D reg:[60h+0eh]~reg:[60h+0fh]&mdash ; 40 ;1 word
E reg:[60h+10h]~reg:[60h+12h]—&mdash ;PDP ;3 byte
变动情况如下:
(1)排名升至38位;(2)收入增加了70;(3)主要产品变为VAX系列。
涉及改动的内存空间分别为上述分布表中的C、D、E三个数据区。
程序如下:
mov ax,seg
mov ds,ax ;设置段地址
mov bx,60h ;设置偏移地址bx,即整个DEC公司数据区的偏移地址
mov si,10h ;设置产品数据区基址
mov word ptr [bx+0ch],38 ;排名修改,字操作
add word ptr [bx+0eh],70 ;收入修改,字操作
mov byte ptr [bx+si+0h],'V'
mov byte ptr [bx+si+1h],'A'
mov byte ptr [bx+si+2h],'X' ;产品数据修改,字节操作
上述程序没有问题,但与书中不同的是对于产品数据区寻址的表示方式,书中为[bx+10h+si]将bx设为整个数据段的基址,10h设为某个数据区的基址,而用si作为变址。这是常规通用的做法,应该去适应。即程序如下:
mov ax,reg
mov ds,ax ;设置段地址
mov bx,60h ;设置偏移地址bx,即整个DEC公司数据区的偏移地址
mov word ptr [bx+0ch],38 ;排名修改,字操作
add word ptr [bx+0eh],70 ;收入修改,字操作
mov si,0 ;设置产品数据的变址
mov byte ptr [bx+10h+si],'V'
inc si
mov byte ptr [bx+10h+si],'A'
inc si
mov byte ptr [bx+10h+si],'X' ;产品数据修改,字节操作
其中[bx+10h+si]还可以写为[bx][si].10h;[bx].10h[si];10h[bx][si]
五、div指令
两种情况:
1、除数为8位,则被除数为16位,在ax中;结果的商在al中,余数在ah中;
2、除数为16位,则被除数为32位,高16位在dx中,低16位在ax中;结果的商在ax中,余数在dx中;
问题8.1
用div计算:data中第一个数据除以第二个数据;商存在第三个数据中
data segment
dd 100001 ;ds:[0]~ds:[3]
dw 100 ;ds:[4]~ds:[5]
dw 0 ;ds:[6]~ds:[7]
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,word ptr [0] ;表示100001的低16字节
mov dx,word ptr [02h] ;表示100001的高16字节
div word ptr [04h] ;因第二个数据为字型,所以除数应为16位
mov word ptr [06h],ax ;商存入数据段第三个数中
...
end start
实验7
assume cs:codesg,ds:data,es:table,ss:stack 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' ; 以上为21个年份的字符串 dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 ;以上为21年公司收入数据 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635 dw 8226,11542,14430,15257,17800 ;以上为21年公司员工人数 data ends table segment db 21 dup ('year summ ne ?? ') table ends ;要求将data段数据按年份写入table段中 stack segment db 16 dup (0) stack ends codesg segment start: mov ax,data mov ds,ax ;源数据区段地址 mov bx,0 mov si,84 mov di,168 mov ax,table mov es,ax ;目标区段地址 mov bp,0 mov ax,stack mov ss,ax mov sp,16 mov cx,21 s: mov ax,[bx+0] mov es:[bp+0],ax mov ax,[bx+2] mov es:[bp+2],ax ;年份数字传递 mov byte ptr es:[bp+4],20h ;设置空格 mov ax,[si] mov es:[bp+5],ax mov ax,[si+2] mov es:[bp+7],ax ;收入数据传递 mov byte ptr es:[bp+9],20h ;设置空格 mov ax,[di] mov es:[bp+10],ax ;员工数据传递 mov byte ptr es:[bp+12],20h ;设置空格 mov ax,[si] mov dx,[si+2] ;设置被除数 div word ptr [di] mov es:[bp+13],ax ;保存商 mov byte ptr es:[bp+15],20h ;设置空格 add bx,4 add si,4 add di,2 add bp,16 ;下次循环条件重设 loop s mov ax,4c00H int 21h codesg ends end start