汇编语言数组操作

删除元素

待删除元素在AX中

数组元素无序,在附加段,首地址为DI,第一个元素为数组长度,比如:

1
2
3
4
cnt dw 6
arr dw 1, 2, 3, 4, 5, 6
......
lea di, cnt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
del_elem    proc    near
cld     ; 正向扫描(DF=0)
push di
mov cx, es:[di] ; 数组长度
add di, 2 ; 现在DI指向第一个元素
repne scasw ; 串扫描(字)
je delete ; 找到后ZF=0,DI指向匹配元素的下一个地址,CX为剩余元素个数
pop di ; 未找到则退出
jmp exit
delete:
jcxz dec_cnt ; CX=0表明是最后一个元素,只要将数组长度减1即可
next_elem: ; 将后面的元素逐个前移
mov bx, es:[di]
mov es:[di-2], bx
add di, 2
loop next_elem
dec_cnt: ; 将数组元素个数减1
pop di
dec word ptr es:[di]
exit:
ret
del_elem endp

插入元素

待插入的数为n(正数)

数组元素递增,首地址为arr_head,尾地址为arr_tail,比如:

1
2
3
x        dw ?    ; 占位
arr_head dw 1, 2, 3, 4, 5
arr_tail dw 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ins_elem    proc    near
mov ax, n
mov arr_head-2, 0ffffh ; 占位为-1,n为正数,n最小时将n放到占位的地方
mov si, 0
compare:
cmp arr_tail[si], ax ; 从后向前查找正确位置
jle insert ; 找到小于等于n的就插入
mov bx, arr_tail[si] ; 否则将大的元素后移
mov arr_tail[si+2], bx
sub si, 2
jmp compare
insert:
mov arr_tail[si+2], ax
ret
ins_elem endp

数组排序

两种冒泡排序,第二种加入了标记,效率高一些

递减排序

数组首地址为arr,n个元素,比如:

1
arr dw n dup(?)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
arr_sort    proc    near
mov cx, n
dec cx ; 外循环n-1趟
loop1: ; 外循环,循环变量保存在di
mov di, cx
mov bx, 0
loop2: ; 内循环,循环变量就是CX
mov ax, arr[bx]
cmp ax, arr[bx+2] ; 比较相邻元素
jge continue ; 符合递减顺序
xchg ax, arr[bx+2] ; 不递减则交换
mov arr[bx], ax
continue:
add bx, 2 ; 内循环
loop loop2
mov cx, di ; 外循环
loop loop1
ret
arr_sort endp

递增排序

数组在附加段中,DI保存数组首地址,第一个元素为数组长度,比如:

1
2
3
4
cnt dw 6
dw 3, 5, 2, 4, 1, 6
......
lea di cnt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
arr_sort    proc    near
mov arr, di ; arr为数据段定义的变量,保存数组首地址
mov cx, es:[di]
mov cnt, cx ; 数组元素个数
init:
mov bx, 1 ; 用作这一趟是否进行了交换的标记
dec cnt ; 外循环cnt-1趟
jz sorted
mov cx, cnt ; 内循环
mov di, arr
next:
add di, 2
mov ax, es:[di]
cmp es:[di+2], ax
jae continue ; 符合递增顺序
xchg es:[di+2], ax
mov es:[di], ax
sub bx, bx ; 交换标记
continue:
loop next
cmp bx, 0
je init ; 没有交换过就表示已经排好序了
sorted:
mov di, arr
ret
arr_sort endp