簡體   English   中英

跟蹤MASM的NCR組裝程序

[英]Tracing a NCR assembly program of MASM

當我們的講師解釋時,我錯過了會議。

我知道NCR的公式

NCR = N! /(R!*(NR)!)

我沒有關注NCR PROC ,因為沒有找到因子,並且那里正在進行一些令人毛骨悚然的遞歸工作。 幫助將非常感激。


print macro str
    lea dx,msg
    mov ah,09h
    int 21h
endm

.model small
.data
    n dw 15
    r dw 6
    ncr dw 1
    msg db "The NCR is : ","$"
.code
     start: mov ax,@data
            mov ds,ax

            mov bx,n
            mov cx,r
            inc bx
            call ncr1
            print msg          
            mov ax,ncr
            call display

            mov ah,4ch
            int 21h

          ncr1 proc
                cmp cx,00      
                  je l1
                push cx         
                dec cx
                call ncr1        
                mov ax,bx       
                pop cx          
                sub ax,cx       
                mul ncr         
                div cx          
                mov ncr,ax      
              l1 : ret
          ncr1 endp

          display proc
                aam
                add ax,3030h
                mov bx,ax
                mov dl,bh
                mov ah,02h
                int 21h
                mov dl,bl
                mov ah,02h
                int 21h                
             ret
      display endp

end start                

好的,我在展示如何分析匯編代碼塊時看到了一些重用價值,所以在這里。


我們在這里處理一個子程序,一段應該相對自治的代碼。

所以,首先,讓我們確定它對程序的原始影響:它的輸入,輸出和對sp - 即它的調用約定簽名

它使用哪些實體不是由它設定的?

ncr1 proc
    cmp cx,00    # <-- cx
      je l1
    push cx
    dec cx
    call ncr1
    mov ax,bx    # <--bx
    pop cx
    sub ax,cx
    mul ncr      # <--ncr
    div cx
    mov ncr,ax
  l1 : ret
ncr1 endp

它修改了哪些實體,之后沒有恢復?

ncr1 proc
    cmp cx,00
      je l1
    push cx      # cx->local_stack[-2]
    dec cx       # -->cx? (overridden)
    call ncr1
    mov ax,bx
    pop cx       # local_stack[-2]->cx => cx restored
                 # (the next step is actually needed to deduce push/pop
                 # correspondence so they should be done in parallel)
    sub ax,cx
    mul ncr      # -->ax,dx
    div cx
    mov ncr,ax   # -->ncr
  l1 : ret
ncr1 endp

僅標記實體的最后更改(因為它們優先於先前的更改)。

它對sp有任何凈效應嗎? (數字是相對於返回地址的當前sp

ncr1 proc
    cmp cx,00
      je l1
    push cx     #-2
    dec cx
    call ncr1   #delta is same as self
    mov ax,bx
    pop cx      #0
    sub ax,cx
    mul ncr
    div cx
    mov ncr,ax
  l1 : ret      #without an argument, only cleans the return address
ncr1 endp

它沒有(因此“與self相同”為0),並且在ret所有情況下都為0 ,確認它正確處理本地堆棧。

最后,它的簽名是:

ncr1 (cx,bx,ncr) -> ax,dx,ncr

axdx可能未被使用(但它們仍然是不穩定的 )。 調用約定是自定義純寄存器,帶有一個硬編碼的輸入/輸出參數。


現在,剩下的就是跟蹤每個實體在任何時候持有的物理 - 然后是概念 - 價值:

ncr1 proc  --initially: bx=N, cx=R (metavariables)
    cmp cx,00    # if R==0:
      je l1      #   ret (ax,dx,ncr unchanged)
    push cx      #[-2]=R
    dec cx       #cx=R-1
    call ncr1    #ncr1(N,R-1) -> ax,dx,ncr(probably the result)
    mov ax,bx    #ax=N
    pop cx       #cx=[-2]=R
    sub ax,cx    #ax=N-R
    mul ncr      #dx:ax=(N-R)*ncr = (N-R)*ncr1(N,R-1)
    div cx       #ax=[(N-R)*ncr1(N,R-1)]/R
    mov ncr,ax   #ncr=[(N-R)*ncr1(N,R-1)]/R
  l1 : ret
ncr1 endp        # -> ax,dx,ncr(the result, now we're sure)

這里是:程序計算(N,R) -> [(NR)*ncr1(N,R-1)]/R其中N=bxR=cx ,結果是ncr (其是變異的)。

看似可疑: (NR)在規范公式中應為(N+1-R) ,符合評論62556150 如果我們用n=N-1代替,它將變成: (n+1,R) -> [(n+1-R)*ncr(n+1,R-1)]/R看起來沒問題(第一個參數永遠不會改變)...所以程序實際上計算nCr(n-1,r)

傳遞n+1的選擇必須是因為n只作為n+1進入公式,所以這樣我們每次都會增加它的周期。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM