1. 程式人生 > >[lc3]彙編實現二分查詢(Binary Search)找函式零點

[lc3]彙編實現二分查詢(Binary Search)找函式零點

Find the zeros of a polynomial

Purpose

(1)主要目標:用BinarySearch的方法實現在給定區間上的單調多項式函式的零點查詢。

(2)具體要求: 1.要求對f(x)的計算採用subroutine來實現,x存放在R0中且將結果存放在R4中,要求不能修改其他暫存器的內容。

                 2.要求必須採用二分查詢。

                 3.

(3)一些前提假設:

1.xlow is always smaller than xhigh.

2.f(x) can always be expressed with 16bits.

3.All intervals will contain a zero. l If f(x)= 0, then x is an integer.

4.f(xlow) and f(xhigh) are not zeros.

5.x1 + x2 can always be expressed with 16bits for all values of x1 and x2 in the interval

Principle

1.     本次實驗中主要分為三個部分,對應三個檔案,其中f(x)的計算以及divide by 2均通過subroutine來實現

2.     f(x)的計算利用了Horner's rule,可以例示為Ax^3 + Bx^2 + Cx + D = ((Ax + B)x + C)x + D。然後通過迴圈迭代的方法實現,每次迭代計算式子Ax + B,然後計算結果作為下一次迭代中的A。

3.     2中提到計算Ax+ B,計算時,針對A的正負採取不同的處理,若A為正則利用累加的方法計算Ax,反之採用的是反覆減去x得到負值。

4.     除以二時採用的時遍歷的方法,遍歷所有同符號絕對值小於被除數的值,然後驗證是否為被除數X的[X/2]。

Procedure

程式碼分析

1.主routine

  .ORIGx3000

              LDIR2,XLOW

              LDIR3,XHIGH

 

LOOP     ADDR0,R2,R3

              LDR6,DIVIDE               ;計算區間中值

              JSRRR6

              LDR6,FUNCTION        ;計算中值處的函式值

              JSRRR6

              ADDR4,R4,#0             ;判斷正負,並據此進行不同跳轉,進行後續判斷

              BRzOVER

              BRnBRANCH

              BRpBRANCH3

              BRnzpLOOP

 

BRANCH ADD R5,R0,#0

              ADDR0,R2,#0

              LDR6,FUNCTION

              JSRRR6               

              ADDR4,R4,#0

BRp BRANCH2            ;判斷一個邊界處函式值正負,若為正則用中值代替此邊界

              ADDR2,R5,#0             ;反之若為負則用種植代替另外一個邊界,下面類似

              BRnzpLOOP               ;本質是判斷符號是否相同,異號才能作為新區間的邊界

 

BRANCH2 ADD R3,R5,#0          

              BRnzpLOOP

 

BRANCH3     ADDR5,R0,#0

              ADDR0,R2,#0

              LDR6,FUNCTION

              JSRRR6

              ADDR4,R4,#0

              BRnBRANCH4

              ADDR2,R5,#0

              BRnzpLOOP

 

BRANCH4 ADD R3,R5,#0

              BRnzpLOOP

 

OVER     STIR0,SAVE

              HALT

SAVE      .FILLx4000

XLOW    .FILLx4001

XHIGH    .FILLx4002

DEGREE  .FILLx4003

START    .FILLx4004

FUNCTION .FILL x5000

DIVIDE    .FILLx6000

.END

2.計算f(x)的subroutine的部分

FUNCTION    STR2,SAVER2

                     ST R3,SAVER3

                     ST R5,SAVER5

                     ST R6,SAVER6              ;儲存呼叫暫存器的初值

      

                     LDI R2,DEGREE

                     LDI R4,START

                     LD R5,START

 

FLOOP   ANDR3,R3,#0

              ADD R4,R4,#0

              BRn NLOOP

 

PLOOP   ADDR3,R3,R0

              ADD R4,R4,#-1

              BRp PLOOP  

              BRnzp CMP   ;R4=0            ;A為正數時累加計算AX

 

NLOOP  NOTR6,R0

              ADD R6,R6,#1

              ADD R3,R3,R6

              ADD R4,R4,#1

              BRn NLOOP                       ;A為負數時累減計算AX

 

 

CMP       ADDR5,R5,#1

              LDR R4,R5,#0

              ADD R4,R3,R4

              ADD R2,R2,#-1

              BRp FLOOP                        ;計算AX+B然後迭代

      

              LD R2,SAVER2

              LD R3,SAVER3     

              LD R5,SAVER5

              LD R6,SAVER6

              RET                                    ;將暫存器的值復原

 

3.divide by 2,主要是遍歷以及判斷,思想較為簡單,此處略去不作分析

 

 

Result

一些測試以及結果驗證:

mark

除法的實現採用遍歷,私以為效率極差,但是未發現更好地方法。除以2用位移操作可能更為方便,但是沒有對應指令。此處也許可以優化。