`
qdujunjie
  • 浏览: 108721 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

汇编语言二分查找排序代码分析(13)

阅读更多

 

来自于《Intel汇编语言程序设计》(第四版)第九章。

 

我们知道二分查找排序是每次比较之后都会将查找范围减半的算法,其算法时间复杂度是O(logN),查找40亿的数据时,其时间也不过30秒左右,非常高效,不过其需要的前提是一个已经按升序或降序排序完成的数据集合。

 

下面看一下原书中用C++实现的适用于有符号整数的二分查找函数:

 

int BinSearch( int values[] , const int searchVal , int count )

{

      int first = 0 ;

      int last = count -1 ;

      while ( first <= last )

      {

            int mid = ( first + last ) / 2

            if ( values[mid] < searchVal )

                 first = mid + 1;

            else if (values[mid] > searchVal)

                 last = mid - 1;

            else

                 return mid;           ; success

      }

      return -1;                        ; not found

}

 

 

原书用汇编语言实现的部分:

 

 

;--------------------------------------------------------------------------------------

BinarySearch PROC uses ebx edx esi edi,

                      pArray:PTR DWORD,             ;pointer to array

                      Count:DWORD,                     ; array size

                      searchVal:DWORD                ; search value

LOCAL first : DWORD,                                 ; frist position

           last : DWORD,                                  ; last position

           mid : DWORD                                   ; midpoint

;

; search an array of signed integers for a single value.

; Receives : Pointer to array , array size , search value.

; Returns : If a match is found ,EAX=the array position of  the

; matching element ; otherwise , EAX=1.

;--------------------------------------------------------------------------------------

         

            mov first , 0                        ; first = 0

            mov eax,Count                   ; last = ( Count - 1 )

            dec eax

            mov last,eax

            mov edi,searchVal              ; EDI = search Val

            mov ebx,pArray                  ; EBX points to the array

 

L1:      ; while first<=last

           mov eax,first

           cmp eax,last

           jg L5                                    ; exit search

           ; mid = ( last + first ) / 2

           mov eax,last

           add eax, first

           shr eax,1

           mov mid,eax

           ; EDX=values[mid]

           mov esi,mid

           shl esi,2                                ; scale mid value by 4

           mov edx,[ebx+esi]                ; EDX=values[mid]

; if ( EDX < searchval[EDI])

; first = mid + 1

           cmp edx,edi

           jge L2

           mov eax,mid                          ; first = mid + 1

           inc eax

           mov first,eax                       

           jmp L4

 

; else if (EDX>searchVal(EDI))

;         last = mid - 1;

L2:     cmp edx,edi                             ; optional

          jle L3

          mov eax,mid                            ; last = mid- 1

          dec eax

          mov last,eax

          jmp L4

         

; else return mid

L3:     mov eax,mid                           ; value found

          jmp L9                                     ; return mid

L4:     jmp L1                                     ; continue the loop

L5:     mov eax,-1                              ; search failed

L9:     ret

BinarySearch ENDP

 

          

 因为以上程序里有几个条件跳转指令,所以先复习一下这些指令格式:

 

jg,jge和jle均基于有符号数指令比较。

 

jg 目的操作数 源操作数

 

如果目的操作数大于源操作数则跳转。

 

 

jge 目的操作数 源操作数

 

如果目的操作数大于或等于源操作数则跳转。

 

 

jle 目的操作数 源操作数

 

如果目的操作数小于或等于源操作数则跳转。

 

 

 

另外还有两个移位指令shl和shr,作用如下:

 

SHL(shift left)指令对目的操作数执行逻辑左移操作。低位以0填充,移出的最高位被送到进位标志(CF)中,原来的进位标志就丢失了。

 

SHL指令格式为:

 

SHL 目的操作数 源操作数

 

而SHR完全与SHL相反,SHR(shift right)指令对目的操作数执行逻辑右移操作。移出的数据以0代替,最低位被送到进位标志(CF)中,原来的进位标志就丢失了。

 

SHL指令格式为:

 

SHL 目的操作数 源操作数

 

下面我们来看一下汇编代码。虽然程序很长,但是并不是很复杂,我们就以注释来代替讲解:

 

 

;--------------------------------------------------------------------------------------

BinarySearch PROC uses ebx edx esi edi,    ; 将寄存器的值先保存

                      pArray:PTR DWORD,               ;pArray为指DWORD类型的数组的指针

                      Count:DWORD,                       ; 数组的长度

                      searchVal:DWORD                  ; 需要查找的值

LOCAL first : DWORD,                                 ; 开始地址

           last : DWORD,                                  ; 结束地址

           mid : DWORD                                   ; 中间地址

;

; search an array of signed integers for a single value.

; Receives : Pointer to array , array size , search value.

; Returns : If a match is found ,EAX=the array position of  the

; matching element ; otherwise , EAX=1.

;--------------------------------------------------------------------------------------

         

            mov first , 0                        ; first = 0

            mov eax,Count                   ; last = ( Count - 1 )

            dec eax

            mov last,eax

            mov edi,searchVal              ; EDI = search Val

            mov ebx,pArray                  ; EBX points to the array

 

L1:      ; while first<=last

           mov eax,first

           cmp eax,last

           jg L5                                    ; 如果first大于last,则退出

           ; mid = ( last + first ) / 2

           mov eax,last

           add eax, first

           shr eax,1                              ; 通过右移位除以2

           mov mid,eax

           ; EDX=values[mid]

           mov esi,mid

           shl esi,2                                ; 因为我们现在操作的是DWORD,所以乘以4

           mov edx,[ebx+esi]                ; 这样得到的就是中间地址,把中间地址的值赋给edx

; if ( EDX < searchval[EDI])

; first = mid + 1

           cmp edx,edi                          ; 如果中间值小于要查找的数

           jge L2                                   ; 如果edx大于等于edi则跳转,否则向下执行

           mov eax,mid                          ; first = mid + 1

           inc eax

           mov first,eax                       

           jmp L4

 

; else if (EDX>searchVal(EDI))

;         last = mid - 1;

L2:     cmp edx,edi                             ; 如果中间值大于要查找的数

          jle L3                                       ; 如果edx小于等于edi则跳转,否则向下执行

          mov eax,mid                            ; last = mid- 1

          dec eax

          mov last,eax

          jmp L4

         

; else return mid

L3:     mov eax,mid                           ; value found

          jmp L9                                     ; return mid

L4:     jmp L1                                     ; continue the loop

L5:     mov eax,-1                              ; 没有找到,返回-1

L9:     ret

BinarySearch ENDP

 

 

此汇编代码完全是按照上面C++代码的逻辑编写。

0
1
分享到:
评论

相关推荐

    汇编输入三门成绩按总分排序

    输入三门学生成绩,姓名学号,输出按总分排序,还可按姓名查找学生信息。

    mips 汇编归并排序和二分查找源码和报告

    I created a complex MIPS assembler program and execute a simulation with SPIM.In my program,I implemented several sub-programs:mergesort,binary search,a sum total value,average,maximum and minimum. ...

    汇编语言程序设计.林邦杰.陈明

    13-2 数组查找 13-3 使用XLATB指令转换 13-4 排序 13-5 队列 13-6 堆栈 13-7 链表 课后习题 第14章 浮点数运算 14-1 80x87协处理器的运算 14-2 浮点堆栈 14-3 状态字 14-4 控制字 14-5 数据类型 14-5-1 二进制整数 ...

    汇编实验报告.doc

    综合实验报告 ( 2010 -- 2011 年度第 一 学期) 名 称: 《汇编语言程序设计》综合实验 班 级: 学 号: 学生姓名: 指导教师: 设计周数: 一周 成 绩: 日期: 2011 年 1 月 3 日 《汇编语言程序设计》综合实验 任 ...

    汇编程序设计 汇编

    在此次课程设计中,我与吕鑫等人一组,我们综合利用了80X86汇编语言程序设计这门课中所学的所有知识,实践操作了多种指令的功能,丰富了用汇编语言编程的经验。也从中体会到了用汇编编程的难处。 在以小组为单位的...

    汇编语言实验及课程设计报告+源程序

    汇编的几次完整的实验报告,包括实验目的,实验内容,源程序和心得体会。源程序有注释。 实验题目如下: 1.比较字符串sample.asm 2.用表格形式显示ASCII字符SMASCII 3.分类统计字符个数COUNT_CHAR 4.查找电话号码...

    汇编课程设计.zip

    本项目为排序与查找功能,具体项目为选择排序,冒泡排序以及二分查找。

    嵌入式作业

    嵌入式作业,涉及arm汇编,对数组进行排序和查找,采用冒泡排序和二分查找算法

    MIPS Assembly Language

    很好的MIPS相关的汇编入门资料,介绍了MIPS的汇编指令,以及如何汇编实现递归、冒泡排序和二分查找等基本应用

    JAVA上百实例源码以及开源项目源代码

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    C语言讲义.doc

    1 愉快的开始-HELLO WORLD 14 1.1 INCLUDE头文件包含 14 1.2 MAIN函数 14 1.3 注释 14 ...6.4.2 二分查找 83 6.5 链表 84 6.5.1 单向链表定义 84 6.5.2 单向链表数据结构定义 85 6.5.3 单向链表的实现 85

    北语15春《计算机科学导论》作业3.doc

    程序设计语言中的汇编语言是一种高级语言。 A. 错误 B. 正确 -----------------选择: 5. 程序源代码经过编译得到的目标程序不可以脱离其语言环境独立执行。 A. 错误 B. 正确 -----------------选择: 6. 死锁是指...

    JAVA上百实例源码以及开源项目

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java开源包8

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    软件设计师重点考点

    1.2 汇编语言: 42 1.3 解释程序: 42 1.4 编译程序: 43 2.重点与难点 45 2.1文法及语言形式描述: 45 2.2 词法分析 46 2.3 语法分析 47 2.4代码优化 48 专题三:操作系统知识 53 1、操作系统知识: 53 1.1基本...

    C#微软培训资料

    2.2 公用语言运行时环境与公用语言规范.13 2.3 开 发 工 具 .17 2.4 小 结 .19 第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 ...

    2005-2009软件设计师历年真题

     • 排序算法、查找算法、数值计算方法、字符串处理方法、数据压缩算法、递归算法、图的相关算法  • 算法与数据结构的关系、算法效率、算法设计、算法描述(流程图、伪代码、决策表)、算法的复杂性  2.计算机...

    Visual C++ 2005入门经典--源代码及课后练习答案

    他曾在IBM工作多年,能使用多种语言进行编程(在多种机器上使用汇编语言和高级语言),设计和实现了实时闭环工业控制系统。Horton拥有丰富的教学经验(教学内容包括C、C++、Fortran、PL/1、APL等),同时还是机械、加工...

    计算机软件水平考试软件设计师考试大纲与培训指南(2009版)

     常用的排序算法、查找算法、数值计算、字符串处理、数据压缩算法、递归算法、图的相关算法  算法描述和分析 2.2.2 操作系统知识  操作系统的内核  处理机管理  存储管理  设备管理  文件管理  ...

Global site tag (gtag.js) - Google Analytics