以上是C语言程序 ;用汇编语言实现实现冒泡排序,并将排序后的数输出 DATAS SEGMENT A dw 5, 5, 3, 7, 4, 2, 5, 4, 9, 1, 8, 6 N=$-A ;计算数字所占的字节数 DATAS ENDS //相当于int a[] = {5, 5, 3, 7, 4, 2, 5, 4, 9, 1, 8, 6};// CODES SEGMENT ASSUME CS:CODES,DS:DATAS START:MOV AX,DATAS MOV DS,AX // 相当于int a[] 中的数组a获得了一个确切的起始地址 MOV SI,0 ;SI遍历数字;前一个数的地址 MOV CX,N/2-1 ;设置循环次数,M(M=N/2)个数需要,循环M-1次 CALL BUBBLE ;调用BUBBLE将原来的数排序 ;输出排序后的数 MOV CX,N/2 ;循环M次输出排序后的M个数 MOV SI,0 ;SI遍历排序后的数 MOV DI,0 ;用DI记录数字的位数 MOV BP,N+5 ;BP用于遍历存储的转化后的字符的位置(因为每个数字占4个字节,中间一个 空格) SHOW: PUSH CX ;循环次数入栈 MOV DX,0 ;由于将要进行16位除需要置高16位为0 MOV AX,[SI] ;低16位为排序后的数 CALL DTOC ;调用DTOC将十进制数转换为字符串 CALL SHOW_STR ;调用SHOW_STR将一个数转化得到的字符串输出 ADD SI,2 ;下一个数 POP CX ;循环次数出栈栈 LOOP SHOW MOV AH,4CH 汇编语言先要将每一个排好序的数字转换为字符串,然后再在屏幕上显示 INT 21H 整个上面这一段相当于for (i=0; i<12; ++i) ;冒泡排序 BUBBLE PROC L1: PUSH CX ;将循环次数入栈 LEA SI,A ;SI遍历DATAS数据段的数字 L2: MOV AX,A[SI] ;将前一个数存于AX CMP AX,A[SI+2] ;比较前后两个数 JBE NEXT ;如果前一个数小于或等于后一个数则继续本轮的比较 XCHG AX,A[SI+2] ;否则,交换前后两个数的位置 MOV A[SI],AX NEXT:ADD SI,2 ;下一个数 LOOP L2 ;注意内层循环的次数已经确定了 POP CX ;将循环次数出栈 LOOP L1 ;下一轮比较 RET BUBBLE ENDP //整个过程与C语言中的冒泡过程一样。注意两者的指针差别:C语言中就是简单的整型变量 i,j,而汇编语言则要指定具体是哪个寄存器// ; 将十进制数转换为字符串并储存起来 DTOC PROC S:MOV CX,10 ;将除数10,放入CX中 CALL DIVDW ;调用DIVDW程序 ADD CL,30H ;把数字转换为ASCII码,这样就能显示了 MOV DS:[BP],CL ;把ASCII码放到内存中 INC DI ;用DI记录循环的次数 PUSH AX ;将低16位入栈 ADD AX,DX ;将高位与低位相加,接着判断是否已经除尽 JZ BACK ;除尽后返回调用处 POP AX ;将低16位出栈 DEC BP ;逆序存放转化后的字符,便于主程序调用SHOW_STR JMP S BACK:POP AX ;为了得到正确的IP值,需要出栈一次 RET DTOC ENDP ;子程序定义开始,功能是分离被除数的各个位的数字 ;公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N DIVDW PROC PUSH AX ;低16位入栈 MOV AX,DX ;将高16位写入AX, MOV DX,0 ;将高16位置零 DIV CX ;将新的数除10, MOV BX,AX ;将商int(H/N)转移到BX,默认余数rem(H/N)在DX POP AX ;将低16位出栈, DIV CX ;将[rem(H/N)*65536+L]除10,默认余数在DX MOV CX,DX ;将余数转移到CX MOV DX,BX ;将商int(H/N)转移到dx,相当于int(H/N)*65536 RET ;子程序定义结束 DIVDW ENDP //C语言中没有这两段,全部隐藏在一句简单的printf('%d ', a[i]);之中// ;实现字符串的输出 SHOW_STR PROC S2:MOV AH,2 ;输出数字转化后的字符串 MOV DL,DS:[BP] INT 21H INC BP ;顺序输出 DEC DI ;数字的位数减一 JZ OK ;字符串输出完了就结束 JMP S2 ;否则继续输出 OK:MOV AH,2 ;输出空格 MOV DL,0 INT 21H RET SHOW_STR ENDP //C语言中也没有这段,同样全部隐藏在一句简单的printf('%d ', a[i]);之中// CODES ENDS END START 由以上对比可以看到,汇编语言中的数字、字符、变量等的地址分配细节,都被高级语言隐藏了,这个过程其实也是一个程序的编译过程;同样数字到字符的转换过程也被隐藏了。所以,用高级语言编写同一个程序,就比用汇编语言要简单得多。 |
|