汇编语言-笔记-第八章及实验7

时间:2021-07-04 04:54:02

第八章 数据处理的两个基本问题
一、寄存器

*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