汇编语言冒泡排序与c语言版冒泡类比

先来看下c语言版的冒泡排序
外循环遍历n - 1次,每次把最大的数"推"到最后,这就是冒泡名字的由来
也就是说每次外循环一次结束后,需要排序的数就减少一个,即内循环比外循环 - i

for (i = 0; i < length - 1; i++) {
    int j = 0;
    for (j = 0; j < length - 1 - i; j++) {
        if (arr[j] > arr[j+1]) {
            int temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
        }
    }
}

然后来看汇编:
(代码思路来自于汇编语言实现冒泡排序这篇博客,思路3也许会有些抽象,本文单独抽出来在文末详细解释一下)
思路:

  1. 本题采用双字节存储,首先用cx记录外套循环次数,每次大循环后,次数-1,每次将cx与0比较,如果等于0,就是循环结束,直接跳出
  2. 用si记录内套循环中当前更换数字的下标,每次外套循环开始时就将si置为0
  3. 将bx加为cx 的两倍来判断内套循环结束的条件,每次都与si比较。
  4. 在内套循环中,将其中一个数据取到寄存器中,与内存数比较,比较完以后,将si+2,因为是采用双字节,所以每一次需要加两个地址单位。
assume cs:code,ds:data,ss:stack
data segment
        arr  dw 7,9,5,8,6,4,10,1,3,2
data ends
stack segment
              db 10 dup (0)
stack ends
code segment
        start:
              mov  ax,data
              mov  ds,ax

              mov  cx,9
        s1:   
              mov  si,0
              cmp  cx,0
              je   exit
              dec  cx                  
              mov  bx,cx               
              add  bx,cx               
        s2:   
              mov  ax,arr[si]
              cmp  ax,arr[si+2]
              jle  s3
              xchg ax,arr[si+2]
              xchg ax,[si]
        s3:   
              cmp  si,bx               
              je   s1                  
              add  si,2                
              jmp  s2


        exit: 
              mov  ax,4c00h
              int  21h

code ends
end start

在上面的思路3中,大家或许会对bx加为cx 的两倍来判断内套循环结束的条件有些难以理解,我们一步一步来看:

  1. 程序从start标号处开始顺序执行,进入s1中先mov si,0 cmp cx,0 je exit,然后dec cx,cx变成8,接下来两步:mov bx,cx add bx,cx意在把cx的两倍赋给bx,此时bx变为16,也就是整个数组对应c代码中的内层循环的 j,一开始j的大小也是整个数组长度
  2. 由于汇编代码是顺序存放的,所以接着顺序执行到s2,这两条mov ax,arr[si] cmp ax,arr[si+2]比较相邻两个数,jle s3表示如果这两个数是≤的关系,就跳转到s3,此时的两个数是7和9,满足条件,所以下面跳转到s3执行
  3. s3中每次先cmp si,bx je s1意在内层循环是否结束,为什么是这个意思呢,咱们接着看add si,2 jmp s2,即si+=2,继续比较后面两个数。那对应到c代码中的哪一句呢?

两段代码对应

  1. 其实整个s3标号里的内容就是内层的for (j = 0; j < length - 1 - i; j++)中的后面两句,而前面的j = 0就对应着s1中的mov si,0
  2. s1标号里的cmp cx,0 je exit对应外层循环的for (i = 0; i < length - 1; i++)中间的判断,dec cx对应i++因为这段汇编中没有数组长度的length,所以cx一开始的9就是数组长度,之后cx就充当了外层循环的计数器
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值