初学汇编语言,自己便许下了用汇编实现冒泡排序算法的”宏愿”,现在也终于实现了一部分。用高级编程语言的思想指导低级编程语言来实现算法,在过去算奢侈,现在可能是一种妥协。我会随着课程的深入来改正这个程序。在这里记录历程。
版本1
include vcIO.inc
; 过程功能:冒泡排序
.data; set data segment
arr dd 10,2,3,2,5,21,32,12,43,12,33,43,54,66,87,89,00,4,2,6; 待排序数组
len1 byte ? ; 数组长度
len2 byte ? ;内层循环边界
fmt byte '%d ',0
.code
main proc
mov len1,lengthof arr
mov ebx,offset arr
mov al,0h ;外层循环变量
;外层循环体
lp:
cmp al,len1
jnb done; 结束循环
; 内层循环体
mov ah, 1h; 内层循环变量
inner:
;内层循环判断索引部分
mov cl,len1
mov len2,cl
sub len2,al
cmp ah,len2
jnb last
movsx esi,ah ;得到待比较的两个元素索引
mov bl,ah
sub bl,1
movsx edi,bl
mov ecx, arr[(type arr)*esi]
mov edx, arr[(type arr)*edi]
cmp ecx,edx
jnb follow ;交换元素
mov edx,arr[(type arr)*esi]
xchg edx,arr[(type arr)*edi]
xchg edx,arr[(type arr)*esi]
follow:
inc ah ;内层循环更新
jmp inner
last:
inc al ;外层变量更新
jmp lp
done:
xor ecx,ecx
mov al,len1
prt:
movsx ebx,al
cmp ecx,ebx
jnb fina
mov edx, arr[(type arr)*ecx]
pushad
invoke printf,offset fmt,edx
popad
inc ecx
jmp prt
fina:
ret ; return to windows
main endp ; (insert additional procedures here)
end main ; end of assembly
版本2(子程序版)
知道和运用之间总是隔着一个三维宇宙😁,这次更新带比例的的相对基址变址寻址,这样就不用单纯的通过改变索引(还是高级语言编程的习惯)来访问数组元素了。
include vcIO.inc
;过程功能
;主程序验证 ,子程序冒泡排序,通过堆栈传递参数
.data
arr dword 10, 2, 3, 2, 5, 21, 32, 12, 43, 12, 33, 43, 54, 66, 87, 89, 00, 4, 2, 6; 待排序数组
fmt byte '%d ',0
.code
main proc
push lengthof arr ;数组长度压栈
push offset arr ;数组首地址压栈
call bubbleSort
add esp,8 ;堆栈平衡
; 打印结果
mov ecx,lengthof arr
mov ebx,offset arr
xor esi,esi
again:
mov eax,[ebx+4*esi]
pushad
invoke printf,offset fmt,eax
popad
inc esi
loop again
bubbleSort proc
push ebp ;保护ebp内容
mov ebp,esp ;取得最低地址堆栈指针
push eax
push ebx
push ecx
push edx
push edi
push esi
mov ebx,[ebp + 8] ;取出数组偏移地址
mov ecx,[ebp + 12] ; 取出数组长度
xor esi,esi ;外层循环变量
outer:
cmp esi,ecx
jnb done ;排序结束跳转
push ecx
sub ecx,esi ;内层循环边界
mov eax,ecx
pop ecx
xor edi,edi ;内层循环变量
inc edi ;内层从1开始,比较arr[i]和arr[i-1]
inner:
cmp edi,eax
jnb next ;内层循环结束
push ecx ; 交换准备
;待修改块
;带比例的基址变址寻址
;mov edx, [ebx + 4 * edi]
;dec edi
;mov ecx, [ebx + 4 * edi]
;inc edi
;带比例的相对基址变址寻址
mov edx, [ebx + 4 * edi]
mov ecx, [ebx + 4 * edi - 4]
cmp edx, ecx
jnb beyond
; 交换数据(待修改块)
;dec edi
;xchg edx, [ebx + 4 * edi]
;inc edi
;xchg edx, [ebx + 4 * edi]
;带比例的相对基址变址寻址
xchg edx, [ebx + 4 * edi - 4]
xchg edx, [ebx + 4 * edi]
beyond:
pop ecx
inc edi
jmp inner
next:
inc esi
jmp outer
done:
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret
bubbleSort endp
ret
main endp
end main