`
qdujunjie
  • 浏览: 110544 次
  • 性别: 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
分享到:
评论

相关推荐

    汇编语言实现学生成绩排序

    本项目"汇编语言实现学生成绩排序"着重于使用低级编程语言——汇编语言来实现这一功能,这对于理解计算机底层工作原理以及优化性能有极大的帮助。 汇编语言是一种面向机器的编程语言,每条指令直接对应于计算机硬件...

    汇编课程设计 实现折半查找

    折半查找,也称为二分查找,是一种在有序数组中搜索特定元素的有效方法。其基本思想是通过不断将搜索范围减半来快速定位目标值。这种算法尤其适用于大型数据集,因为它的平均时间复杂度为O(log n),比线性查找的O(n)...

    汇编语言实验报告

    在汇编语言中,线性搜索或二分查找等方法可以被实现。这需要理解循环结构(如LOOP指令)以及如何在内存中定位和读取数据。 4. **混合编程**:汇编语言与C语言混合编程是提高性能的一种策略。C语言提供了高级抽象,...

    排序、加法、乘法、查找汇编程序

    查找操作在各种算法中都有应用,如二分查找、线性查找等。在汇编语言中,查找可能涉及对数组的遍历,比较目标值与数组元素,并根据比较结果调整搜索方向。MASM2012中,程序员需熟练掌握跳转指令(如JMP、JNE等),...

    (汇编语言)学生成绩管理系统

    这可能涉及到线性搜索或二分搜索算法的实现,取决于数据结构和排序方式。汇编语言中,查找操作涉及条件分支指令和循环结构。 3. **按成绩排序输出**:系统能够按照成绩对学生信息进行排序,并显示排序后的结果。这...

    汇编实现电话号码查找

    而二分搜索则适用于已排序的数据,每次比较中间元素,根据比较结果缩小搜索范围。在汇编中,这需要使用循环结构(如`LOOP`)、条件分支(如`JNE`,不相等则跳转)和比较指令(如`CMP`)。 5. **程序流程**: - ...

    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. ...

    8086汇编实现冒泡排序、直接插入排序、折半查找

    **折半查找**(二分查找)是一种在有序数组中查找某一特定元素的搜索算法。查找过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或...

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

    14. 数据结构:讲述数组声明、数组查找、使用XLATB指令转换、排序、队列、堆栈和链表等数据结构在汇编语言中的应用。 15. 浮点数运算:涉及80x87协处理器的运算、浮点堆栈、状态字和控制字、数据类型、指令集等内容...

    汇编查找电话号码的程序设计

    - 查找算法:采用线性搜索或者二分搜索,前者适用于未排序的表,后者则要求表已经排序。考虑到人名排序的需求,二分搜索可能是更高效的选择。 4. **程序流程**: - 用户交互:通过提示符引导用户输入人名和电话...

    汇编语言视频教程-(小甲鱼主讲全套77讲)(包含源码-视频-笔记).docx

    - **排序算法实现**:使用汇编语言实现快速排序、冒泡排序等常见排序算法。 - **操作系统内核模块开发**:尝试开发一个简单的操作系统内核模块,如设备驱动程序。 #### 五、学习建议 - **多动手实践**:理论结合...

    汇编语言程序设计

    汇编语言可以用来创建高效的查找算法,例如二分查找或哈希表。在处理电话号码时,可能需要根据特定的格式(如区号、用户号码等)进行搜索,汇编语言允许程序员精确控制数据的存储和访问,从而实现快速的查找功能。 ...

    汇编语言四个实验算法图

    4. **算法实现**:实验中的“算法图”可能表示了如何用汇编语言实现简单的算法,如排序(冒泡排序、选择排序)、搜索(线性搜索、二分查找)或其他基础数学计算。 5. **文档分析**:提供的Doc文件可能包含实验步骤...

    汇编语言设计报告论文

    该报告的核心任务是设计一个汇编语言程序,该程序能够接收用户输入的一串字符(不超过100个),对这些字符进行分类排序并显示。分类标准包括数字、字母和其他字符。数字类先显示,其次是字母类,最后是其他类。同时...

    汇编课程设计.zip

    "汇编二分查找.txt"文件会展示如何利用汇编语言的条件分支和索引操作来实现高效的二分查找算法。 通过分析这些文件,我们可以深入学习汇编语言的基础语法、控制结构(如循环和条件语句)、数据处理(如存储和读取...

    汇编语言程序集(微机原理与接口技术解答题选集)

    汇编语言可实现线性搜索、二分查找等算法,同时也能用于错误检测,如奇偶校验。 5. **统计排序**:汇编语言可以实现各种排序算法,如冒泡排序、选择排序、插入排序和快速排序,这些算法对于优化数据处理速度至关...

    汇编语言实验,包括比较字符串,查找电话号码,分类统计字符个数,用表格形式显示字符

    在汇编语言中查找特定电话号码可能涉及线性搜索或二分查找等算法。线性搜索是从头到尾逐个比较每个元素,直到找到目标或遍历完整个数组。而二分查找则需要已排序的数据,通过不断缩小查找范围来提高效率。电话号码...

Global site tag (gtag.js) - Google Analytics