你给的代码是对一个结构数据数组的冒泡排序,不太容易看懂。下面的程序是对word数组的冒泡排序,要简单得多,也好理解。
程序中还附有选择排序的汇编代码,编制这个程序是为了比较是汇编快,还是pascal语言快!
供参考。
{$G+} {$R-,S-}
uses dos;
const
n=32000;
type
arr=array[1n] of word;
var
a:arr;
b:^arr;
i,j,maxi,max,num,t:word;
h0,m0,s0,ss0,h,m,s,ss:word;
t1,t2:longint;
begin
new(b);
randomize;
num:=n-1;
for i:=1 to n do a[i]:=random(10000)+1;
b^:=a;
{以下为pascal冒泡排序}
a:=b^;
gettime(h0,m0,s0,ss0);
for i:=1 to n-1 do
for j:=1 to n-i do
if (a[j]<a[j+1]) then
begin t:=a[j]; a[j]:=a[j+1]; a[j+1]:=t; end;
gettime(h,m,s,ss);
t1:=(h03600+m060+s0)100+ss0;
t2:=(h3600+m60+s)100+ss;
writeln('pascal冒泡=',t2-t1);
{for i:=1 to n do writeln(a[i]);}
writeln;
{以下为pascal选择排序}
a:=b^;
gettime(h0,m0,s0,ss0);
for i:=1 to n-1 do begin
maxi:=i;
max:=a[i];
for j:=i+1 to n do
if (a[j]>max) then begin maxi:=j; max:=a[j]; end;
if (i<>maxi) then begin t:=a[i]; a[i]:=a[maxi]; a[maxi]:=t; end;
end;
gettime(h,m,s,ss);
t1:=(h03600+m060+s0)100+ss0;
t2:=(h3600+m60+s)100+ss;
writeln('pascal选择=',t2-t1);
{for i:=1 to n do writeln(a[i]);}
writeln;
{以下为汇编冒泡排序}
a:=b^;
gettime(h0,m0,s0,ss0);
asm
mov ax,seg a
mov ds,ax
mov es,ax
{dec word ptr[num] } {数num减一,因为从0开始}
mov cx,num
lea di,a
@1:
push cx
mov bx,0
@2: mov ax,word ptr[di][bx]
cmp ax,word ptr[di][bx+2]
jge @3
mov dx,word ptr[di][bx+2]
mov word ptr[di][bx+2],ax
mov word ptr[di][bx],dx
@3: inc bx
inc bx
loop @2
pop cx
loop @1
end;
gettime(h,m,s,ss);
t1:=(h03600+m060+s0)100+ss0;
t2:=(h3600+m60+s)100+ss;
writeln('汇编冒泡=',t2-t1);
{for i:=1 to n do writeln(i:6,a[i]:6);}
writeln;
{以下为汇编选择排序}
a:=b^;
gettime(h0,m0,s0,ss0);
asm
mov ax,seg a
mov ds,ax
mov es,ax
mov cx,num
lea di,a
mov bx,0
@@1:
push cx
mov si,di
inc si
inc si {si=di+2}
push di {保存di }
mov ax,[di][bx] {假设max 为第一个}
@@2: mov dx,[si][bx] {存储器到寄存器,节省时间}
cmp ax,dx
jge @@3
mov di,si {小于时,将si替换di,即将j替换i, 保存maxi}
mov ax,dx {保存max 到ax}
@@3: inc si
inc si
loop @@2
mov si,di {还原si,即将i替换j}
pop di {取出栈中保存的i}
cmp di,si {与j 比较}
je @@4 {相同时不交换}
mov ax,[di][bx] {在内循环之外交换}
xchg ax,[si][bx]
mov [di][bx],ax
@@4: inc bx
inc bx
pop cx
loop @@1
end;
gettime(h,m,s,ss);
t1:=(h03600+m060+s0)100+ss0;
t2:=(h3600+m60+s)100+ss;
writeln('汇编选择=',t2-t1);
{for i:=1 to n do writeln(i:6,a[i]:6);}
writeln;
dispose(b);
end
==============================
计算结果:
pascal冒泡=900
pascal选择=275
汇编冒泡=560
汇编选择=302
这个程序有点错误的
START:MOV
AX,@DATA
MOV
DS,AX
MOV
CX,N
(N=($-BUF)/2)
DEC
CX
;CX设置为循环的次数,数据是以字存储所以等于数据长度/2-1
LOOP:MOV
DX,CX
;用DX存储循环次数,内层循环完成后再还原给CX
MOV
BX,0
LOOP2:MOV
AX,BUF[BX]
;第一个数据传到AX
CMP
AX,BUF[BX+2]
JGE
NEXT
;第一个数据和第二个数据比较,如果大转到NEXT
EXCH
AX,BUF[BX+2]
;AX和第二个数据对换,此时AX=第一个数,EXCH应改成XCHG
MOV
BUF[BX],AX
;再把AX的值传送个第一个数据,此时AX=第二个数,这样就实现了两数相换
NEXT:
MOV
AX,BUF[BX+2]
;这句应改成ADD
BX,2,否则一直在比较第一,二个数。BX+2指向第二个数据,下次循环时进行第二,三数比较
LOOP
LOOP2
MOV
CX,DX
LOOP
LOOP1
首先你写的程序的loop lp2处应该改为loop lp1。这个也许是你粗心。还有个算法上的错误,就是你写的冒泡排序只进行了一趟。程序帮你改好了,可以改进的地方是设一个交换标志,初始值设为0,若一趟排序中进行过交换,就置交换标志为1。每趟排序完后检查交换标志,若为0则表示排序完成,退出循环(这个功能没写上去,你自己去完成吧)
DATA SEGMENT
X DW 3,7,0,6,0,1,0,8
X_LEN DW 8
DATA ENDS
STACK SEGMENT STACK
DW 200 DUP()
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
MOV CX,X_LEN
DEC CX
lp0:push cx
mov cx,7
LEA SI,X
LP1: MOV AX,[SI]
CMP AX,[SI+2]
JBE LP2
XCHG AX,[SI+2]
MOV [SI],AX
LP2: ADD SI,2
LOOP LP1
pop cx
loop lp0
MOV CX,X_LEN
LEA BX,X
LP3: MOV DL,[BX]
OR DL,30H
MOV AH,2
INT 21H
ADD BX,2
LOOP LP3
MOV AX,4C00H
INT 21H
CODE ENDS
END START
int i,j,temp,n[11];
/n为接受的参数数组(下标为0到10)
for(i=1;i<10;i++)
{
for(j=i+1;j<11;j++)
{
/判断结果为n[i]是本循环中最小数
if(n[i]>n[j])
{
temp=n[i];
n[i]=n[j];
n[j]=temp;
}
}
}
冒泡排序程序如下:
ORG 0000H
LCALL SORT ; 跳转到排序程序
SJMP $ ; 。
SORT: ; 数据冒泡排序程序
MOV R6, #16 ;参加排序数据的总个数
DEC R6 ; 比较次数 比 数据总数 少 1
L1:
MOV R0, #40H ; 把数据的起始地址40h付给R0
MOV A, R6 ;调整比较次数
MOV R7, A
CLR F0 ; 清交换标志
L2: ;比较
MOV A, @R0 ; 取前一个数
INC R0
MOV B, @R0 ; 取后一个数
CJNE A, B, L3 ; 前面的数 与 后面的数 比较, 前-后
L3: ;判断、处理
JC N_JH ; 后面的数 大于 前面的数,不交换
XCH A,B ; 否则前后两数交换存放
MOV @R0,A
DEC R0
MOV @R0,B
INC R0
SETB F0 ; 设交换标志
N_JH:
DJNZ R7, L2 ; 没有比较完,就继续
JNB F0, L_END ; 没有交换过,就结束
DJNZ R6, L1
L_END:
RET ; 排序完成。
;结果是:
;40H中存放着最小的数;
;4FH中存放着最大的数。
data segment;定义数据段
org 2000
arr db 5,2,1,0,2,3,8,6,5,9
count equ $-arr
data ends
code segment;定义代码段
assume cs:code,ds:data
start:
;初始化待排序列
lea si,arr
mov dx,count
Foaming:
;不足两个元素,已有序
sub dx,1
jle endfoaming
xor bx,bx
mov cx,dx
Foaminglop:
;开始一趟排序
mov ax,[si][bx]
cmp ax,1[si][bx]
jle next
;逆序则交换
swap:
push ax
mov ax,1[si][bx]
mov [si][bx],ax
pop ax
mov 1[si][bx],ax
next:
;继续本趟排序
inc bx
loop Foaminglop
;开始下趟排序
jmp Foaming
endfoaming:
;结束排序
mov ax,4c00h
int 21h
code ends;结束程序
N equ 10
model small
data
array dw N dup()
code
main proc far
mov ax,@data
mov ds,ax
mov cx,N
dec cx
loop1:
mov di,cx
mov bx,0
loop2:
mov ax,array[bx]
cmp ax,array[bx+2]
jge cotinue
xchg ax,array[bx+2]
mov array[bx],ax
cotinue:
add bx,2
loop loop2
mov cx,di
loop loop1
exit:
mov ax,4c00h
int 21h
main endp
end main
DATA SEGMENT
A DW 12CH,0FAH,118H,0F0H,104H;此处进行数据的初始化(包含要进行显示的各种提示性语言)
N EQU 4
AVG DW
M DW 10D
P DW 3D
D DW 2
BUF1 DB 'YUAN SHI SHU JU:','$'
BUF2 DB 0DH,0AH,'PAI XU HOU SHU JU:','$'
BUF3 DB 0DH,0AH,'ZUI DA ZHI:','$'
BUF4 DB 0DH,0AH,'ZUI XIAO ZHI:','$'
BUF5 DB 0DH,0AH,'PING JUN ZHI:','$'
BUF6 DB 0DH,0AH,'ER JI ZHI PING JUN ZHI:','$'
DATA ENDS
STACK SEGMENT
DW 100 DUP ()
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA
GO: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET BUF1 ;显示未排序的提示符
MOV AH,09H
INT 21H
MOV CX,N+1
LEA SI,A
LOOP1: CALL ZH ;进行未排序的数据显示
LOOP LOOP1 ;循环5次,因为有5个数
;开始排序
CLD
MOV CX,N
LOOP2: PUSH CX
LEA SI,A ;取数据区的第一个数的偏移量
LODSW ;取第1个数存入AX
LP1: MOV BX,AX ;开始内部排序第5-CX次
LODSW ;取第6-CX个数
CMP BX,AX ;比较两个数大小
JL L1 ;前面数小的话符合要求跳转,大的话换位
MOV [SI-2],BX ;大的数到后面
MOV [SI-4],AX ;小的数到前面
MOV AX,[SI-2] ;改变AX的值
L1: LOOP LP1 ;小循环CX减1
POP CX ;d出外部循环计数
LOOP LOOP2
;输出排序后的结果
MOV DX,OFFSET BUF2
MOV AH,09H
INT 21H
MOV CX,N+1 ;因为有五个数,所以计数寄存器CX置5
LEA SI,A
LOOP3: CALL ZH ;排序后结果显示
LOOP LOOP3
;输出最大值
MOV DX,OFFSET BUF3
MOV AH,09H
INT 21H
LEA SI,A
ADD SI,8H ;最大值现在排在最后,所以SI要进行加8处理
CALL ZH
;输出最小值
MOV DX,OFFSET BUF4
MOV AH,09H
INT 21H
LEA SI,A
CALL ZH
;输出去掉最大最小值的平均值
MOV DX,OFFSET BUF5
MOV AH,09H
INT 21H
MOV AX,[SI] ;因为前一个调用已经将SI指向了第二个数据
MOV BX,[SI+2] ;取第二个数据
ADD AX,BX
MOV BX,[SI+4] ;取第三个数据(这样相加相当于去掉了最大最小值)
ADD AX,BX
CWD
DIV P ;把相加和除以三来求得平均值
LEA SI,AVG
MOV [SI],AX ;把求得的平均值存入AVG
CALL ZH
;输出2进制的平均数
MOV DX,OFFSET BUF6
MOV AH,09H
INT 21H
MOV CX,16D
LEA SI,AVG
MOV AX,[SI]
LP2: CWD
IDIV D ;采用不断除以二并压入栈的方式得到数据的二进制表示方式
PUSH DX
LOOP LP2
MOV CX,16D
LP3: POP DX
ADD DL,30H ;将数据d出站并且加30H进行ASCII的转换
MOV AH,2
INT 21H
LOOP LP3
MOV AH,4CH
INT 21H
ZH PROC ;转换子程序(SI指针由外部提供,方便选择要显示的东西)
LODSW
MOV BX,3 ;数据在十进制时的是三位数所以计数部分BX置三
ZL1: CWD
DIV M ;采用除以10的方法不断得到每一位数
PUSH DX ;将每一位压入栈
DEC BX
JNZ ZL1
MOV BX,3
ZL2: POP DX ;压完一个数后立即出栈进行显示
ADD DL,30H
DEC BX
MOV AH,2
INT 21H
JNZ ZL2
MOV DL,20H ;每个数据间由空格隔开
MOV AH,2
INT 21H
RET ;子程序结束
ZH ENDP
CODE ENDS
END G
以上就是关于求注释汇编冒泡排序代码全部的内容,包括:求注释汇编冒泡排序代码、谁来解释一下冒泡排序法(汇编)的代码啊、汇编 冒泡排序 求高手等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)