求注释汇编冒泡排序代码

求注释汇编冒泡排序代码,第1张

你给的代码是对一个结构数据数组的冒泡排序,不太容易看懂。下面的程序是对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

以上就是关于求注释汇编冒泡排序代码全部的内容,包括:求注释汇编冒泡排序代码、谁来解释一下冒泡排序法(汇编)的代码啊、汇编 冒泡排序 求高手等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9303603.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存