;<<线性表顺序存储结构>>
ASSUME CS:CODES
;定义线性表的内存空间maxsize
datas segment
dw 40 dup(0)
datas ends
;保存线性表一些属性的空间
;属性:线性表最大长度maxsize,线性表的实际长length,线性表每个元素(结点)占内存的大小
attributes segment
dw 40 , 0 , 2
attributes ends
CODES SEGMENT
START:
;添加一个数据B
mov ax , 'B'
call addElement
call printList ;显示表中数据
;在0位置插入元素R
mov ax , 0
mov dx , 'R'
call insert
call printList
;修改1号元素B为A
mov ax , 1
mov dx , 'A'
call update
call printList
;取0号的数据值,返回值在dx中
mov ax , 0
call getData
call printChar
call CRandLF
;删除第0号元素
mov ax , 0
call delete
call printList
mov ah , 07H ;任意键退出
int 21h
MOV AH,4CH
INT 21H
;========================================================
;得到线性表的长度,得到的长度放到AX中
getLength:
push ds
push bx
mov bx , attributes
mov ds , bx
mov ax , ds:[2]
mov ds,bx
pop bx
pop ds
ret
;============================================================
;添加线性表元素,参数放到ax,返回参数ax,ax=0 添加失败 , ax=1 添加成功
addElement:
push ds
push bx
push si
push di
;计算出添加新元素的位置,放到si中
mov bx , attributes
mov ds , bx
mov bx , ds:[0] ;线性表的maxsize
cmp ds:[2] , bx
jnb addErro ;不小于线性表的maxsize,无法添加
push ax
mov ax, ds:[4] ;线性表元素的大小
mul word ptr ds:[2] ;添加元素的位置,结果放到了ax中
mov si , ax
pop ax
mov bx , datas ;添加元素
mov ds , bx
mov ds:[si] , ax
mov bx , attributes ;线性表长度加1
mov ds , bx
add word ptr ds:[2] , 1
mov ax , 1 ;参数返回值
jmp addRet
addErro:
mov ax , 0
addRet:
pop di
pop si
pop bx
pop ds
ret
;============================================================
;从末尾删除元素 , 返回值 ax = 0 删除失败;ax = 1 删除成功
deleteTail:
push ds
push bx
push dx
push si
mov bx , attributes
mov ds , bx
call getLength
cmp ax , 0 ;length == 0 ,表空
je delTailErro
mul word ptr ds:[4]
mov si , ax
push ds
mov bx , datas
mov ds , bx
mov word ptr ds:[si-2] , 0H
pop ds
sub word ptr ds:[2] , 1 ;最后一个元素清零
mov ax , 1 ;length 减 1
jmp delTailRet
delTailErro:
mov ax , 0
delTailRet:
pop si
pop dx
pop bx
pop ds
ret
;============================================================
;删除元素,ax为要删除元素的索引,从0开始,返回参数也放到ax中,ax=0 删除失败;ax=1删除成功
delete:
push ds
push bx
push cx
push si
push di
mov bx , attributes
mov ds , bx
cmp word ptr ds:[2] , 0 ;线性表长度为0没有元素
je delErro
cmp ax ,0;
jb delErro ;索引小于1,左越界无法删除
mov bx , ds:[2]
sub bx , 1
cmp ax , bx ;与线性表最大索引值length-1做比较
ja delErro ;索引大于length-1,右越界,无法删除
sub bx , ax ;求出两索引间的距离,用于删除后的数据移动
mov cx , bx
;求出索引为ax的元素在表中的位置
push ax
mov di , ds:[4]
mul di ;默认为32位乘法,被乘数在AX,结果在AX
mov si , ax
pop ax
mov bx,datas
mov ds,bx
mov bx , si
mov word ptr ds:[bx] , 0 ;清空数据(相当于删除),避免影响
cmp cx , 0 ;判断cx是否为零,为零则不执行movLeft,因为说明这时的索引值=maxsize
je movOver
movLeft: ;将删除元素之后的元素向左移动位置
mov ax , ds:[bx+di]
mov word ptr ds:[bx+di] , 0 ;移位后,清空内存,防止影响
mov ds:[bx] , ax
add bx , di
loop movLeft
movOver:
mov ax , attributes
mov ds , ax
sub word ptr ds:[2] , 1 ;表长度减少1
mov ax , 1 ;返回值
jmp delRet
delErro:
mov ax , 0
delRet:
pop di
pop si
pop cx
pop bx
pop ds
ret
;============================================================
;插入元素,ax表示插入位置的索引,dx为元素内容;返回参数ax = 0 插入元素失败 ,ax = 1 插入元素失败
insert:
push ds
push bx
push cx
push si
push di
mov bx , attributes
mov ds , bx
mov bx , ds:[0]
cmp ds:[2] , bx ;实际长度length >= maxsize , 表满,不能插入length = maxsize时,添加到最末尾
jnb insErro
mov bx , ds:[2]
cmp ax , bx ;当length=0,ax=0 或 ax = length 的时候,即表为空或索引为length的时候,直接添加
jne insIndex
push dx
mul word ptr ds:[4]
mov si , ax ;把ax值放到si中来寻址
pop dx
mov bx , datas
mov ds , bx
mov word ptr ds:[si] , 0 ;清零
mov ds:[si] , dx ;0位置插入元素
mov bx , attributes
mov ds , bx
add word ptr ds:[2] , 1
mov ax , 1 ; 返回值
jmp insRet
insIndex:
cmp ax , 0 ;ax索引小于零,左越界,无法插入
jb insErro
cmp ax , bx
ja insErro ;插入的索引 ax > 最大的索引值+1(不是在表尾添加)bx ,右越界,不能插入
;在指定的ax位置,插入元素
;首先,从ax处开始,数据全部右移
push bx
mov bx , attributes
mov ds , bx
mov di , ds:[4] ;每个数据的内存大小
mov bx , datas
mov ds , bx ;ds值定位到表
pop bx
push ax ;计算增加一个元素后,最后一个元素内存的地址
push dx ;32位乘法会影响dx
mov ax , di ;ax中是每个元素的内存大小
mul bx ;得到目前最大索引后一个的内存地址,即增加后最表尾的地址,返回结果在ax中
mov si , ax ;将ax值给si保存
pop dx
pop ax
sub bx , ax
mov cx , bx ;要移动的数据个数
mov bx , si
movRight:
mov word ptr ds:[bx] , 0 ;移动前将要接收前一个数据的内存清零
sub bx , di
mov ax , ds:[bx] ;数据后移一个位置
mov ds:[bx+di] , ax
loop movRight
mov word ptr ds:[bx] , 0
mov ds:[bx] , dx ;最后将dx中的数据插入到腾出的相对应索引位置的空间上。
mov bx , attributes
mov ds , bx
add word ptr ds:[2] , 1
mov ax , 1 ;操作成功返回值
jmp insRet
insErro:
mov ax , 0
insRet:
pop di
pop si
pop cx
pop bx
pop ds
ret
;============================================================
;修改线性表中的某个元素,ax表示要修改的元素的索引值,dx表示新的内容。返回值ax=0修改失败;ax=1修改成功。
update:
push ds
push bx
push si
push di
cmp ax , 0
jb updErro ;索引值小于零,左越界,不能修改
mov bx , attributes
mov ds , bx
cmp ax , ds:[2]
jnb updErro ;索引值大于等于length,右越界,不能修改
push dx
mul word ptr ds:[4] ; ax乘以每个元素所占的内存大小,结果放到ax中.32为乘法影响dx,先做了保存。
pop dx
mov si , ax ;用来寻址
mov bx , datas
mov ds , bx
mov word ptr ds:[si] , 0 ;该处内存先清零
mov ds:[si] , dx ;修改指定的内存中的数据
mov ax , 1 ;修改成功的返回值
jmp updRet
updErro:
mov ax , 0
updRet:
pop di
pop si
pop bx
pop ds
ret
;=======================================================
;取线性表某个元素,ax表示要取得的元素的索引,dx是返回的取得的数据。返回值ax=0操作失败;ax=1操作成功
getData:
push ds
push bx
push si
cmp ax , 0
jb getdErro ;索引值小于零,左越界,无值可取
mov bx , attributes
mov ds , bx
cmp ax , ds:[2]
jnb getdErro ;索引值大于等于length,右越界,无值可取
push dx
mul word ptr ds:[4] ; ax乘以每个元素所占的内存大小,结果放到ax中.32为乘法影响dx,先做了保存。
pop dx
mov si , ax ;用来寻址
mov bx , datas
mov ds , bx
mov dx , 0 ;对dx寄存器先清零
mov dx , ds:[si] ;将指定内存的数据放到dx中
mov ax , 1 ;操作成功的返回值
jmp getdRet
getdErro:
mov ax , 0
getdRet:
pop si
pop bx
pop ds
ret
;=======================================================
;按给定的值,查找其在线性表中第一次出现的位置的索引值,ax表示给定的值,dx表示返回的索引值。返回值 ax=0 查找失败;ax=1查找成功
search:
push ds
push bx
push si
push di
mov bx , datas
mov di , bx ;保存表的段地址,备用
mov bx , attributes
mov ds , bx
cmp word ptr ds:[2] , 0
jna seaErro ;表长度不大于零,表空无值
mov si , ds:[4] ;表中数据所占内存大小
mov bx , 0 ;使用ds:[bx]寻址形式
mov dx , 0 ;记录索引的寄存器dx归零
mov cx , ds:[2] ;设置循环变量cx为length
mov ds , di ;表的段地址
finding:
cmp ds:[bx] , ax ;比较内存中的数据和给定的ax值是否相同
je find
add bx , si
add dx , 1
loop finding
seaErro:
mov ax , 0
jmp seaRet
find:
mov ax , 1
seaRet:
pop di
pop si
pop bx
pop ds
ret
;==============================
;显示一个字符,默认参数放dl
printChar:
push ax
mov ah , 02H
int 21h
pop ax
ret
;==============================
;回车,换行
CRandLF:
push dx
push ax
mov dl , 0DH
mov ah , 02H
int 21h
mov dl , 0AH
mov ah , 02
int 21h
pop ax
pop dx
ret
;==============================
;遍历显示表中的数据
printList:
push ds
push ax
push bx
push cx
push dx
push si
push di
mov bx , attributes
mov ds , bx
cmp word ptr ds:[2] , 0 ;表为空
je listRet
mov cx , ds:[2]
mov bx , datas
mov ds , bx
mov bx , 0
listAll:
mov dl , ds:[bx]
call printChar
mov dl , ds:[bx+1]
call printChar
add bx , 2
loop listAll
call CRandLF
jmp listRet
listRet:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop ds
ret
CODES ENDS
END START
[07/09/21] |