i8d086.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 807 行 · 第 1/2 页

ASM
807
字号
quotient        label   near
                mov     qu_k[bp],ax
                mov     bx,di
                call    zero
                xor     dl,dl
                lea     di,8[di]
                lea     si,8[si]
quotient_loop   label   near
                mov     ah,dl
                dec     si
                xor     dx,dx
                mov     al,ss:[si]
                test    ax,ax
                je      quick_divide
                div     word ptr qu_k[bp]
quick_divide:   dec     di
                mov     ss:[di],al
                cmp     bx,di
                jne     quotient_loop
                ret

; trial( tr[bp], d[bp], ld_k[bp], ld_m[bp] ) ax
trial           label   near
                mov     si,ld_k[bp]
                add     si,ld_m[bp]
                xor     dx,dx
                mov     ax,tr-2[si+bp]
                mov     dl,tr[si+bp]
                mov     si,ld_m[bp]
                div     word ptr d-2[bp+si]
                test    ax,0ff00h
                je      trial_ok
                mov     ax,0ffh
trial_ok:       ret

; smaller( tr, tq, ld_k, ld_m ) ax
smaller         label   near
                mov     di,ld_m[bp]
smaller_loop:   test    di,di
                je      smaller_done
                mov     si,ld_k[bp]
                add     si,di
                mov     al,tq[bp+di]
                sub     al,tr[bp+si]
                jne     smaller_ret
                dec     di
                jmp     smaller_loop
smaller_done    label   near
                mov     si,ld_k[bp]
                add     si,di
                mov     al,tq[bp+di]
                sub     al,tr[bp+si]
smaller_ret:    ret

; difference( tr, tq, k, m )
difference      label   near
                xor     di,di
                xor     cl,cl
diff_loop:      cmp     di,ld_m[bp]
                jg      diff_done
                mov     si,ld_k[bp]
                add     si,di
                xor     ch,ch
                xor     ax,ax
                mov     al,tr[bp+si]
                sub     ch,cl
                sbb     al,tq[bp+di]
                mov     tr[bp+si],al
                sbb     cx,cx
                inc     di
                neg     cx
                jmp     diff_loop
diff_done       label   near
                ret

; subtract( ss:di o, ss:si e )  o -= e
subtract        label   near
                mov     ax,ss:[di]
                sub     ax,ss:[si]
                mov     ss:[di],ax
                mov     ax,ss:2[di]
                sbb     ax,ss:2[si]
                mov     ss:2[di],ax
                mov     ax,ss:4[di]
                sbb     ax,ss:4[si]
                mov     ss:4[di],ax
                mov     ax,ss:6[di]
                sbb     ax,ss:6[si]
                mov     ss:6[di],ax
                mov     ax,ss:8[di]
                sbb     ax,ss:8[si]
                mov     ss:8[di],ax
                ret

; longdivision( x[bp] x, y[bp] y, q[bp] q, r[bp] r, ld_n[bp] n, ld_m[bp] m )
longdivision    label   near
                mov     di,ld_m[bp]
                dec     di
                xor     bx,bx
                mov     bl,y[bp+di]
                inc     bx
                mov     ax,0100h
                xor     dx,dx
                div     bx
                mov     ld_f[bp],ax
                lea     di,tr[bp]
                lea     si,x[bp]
                call    product
                mov     ax,ld_f[bp]
                lea     di,d[bp]
                lea     si,y[bp]
                call    product
                lea     bx,q[bp]
                call    zero
                mov     cx,ld_n[bp]
                sub     cx,ld_m[bp]
ld_loop:        test    cx,cx
                jl      ld_done
                mov     ld_k[bp],cx
                call    trial
                mov     ld_qt[bp],ax
                lea     si,d[bp]
                lea     di,tq[bp]
                call    product
                call    smaller
                jbe     ld_not_smaller
                dec     word ptr ld_qt[bp]
                lea     si,d[bp]
                lea     di,tq[bp]
                call    subtract
ld_not_smaller  label   near
                mov     di,ld_k[bp]
                mov     ax,ld_qt[bp]
                mov     q[bp+di],al
                call    difference
                mov     cx,ld_k[bp]
                dec     cx
                jmp     ld_loop
ld_done         label   near
                test    byte ptr what_reqd[bp],1
                je      ld_ret
                mov     ax,ld_f[bp]
                lea     di,r[bp]
                lea     si,tr[bp]
                call    quotient
ld_ret:         ret

; negate( ss:bx )
negate          label   near
                xor     cx,cx
                mov     ax,cx
                sub     ax,ss:[bx]
                mov     ss:[bx],ax
                mov     ax,cx
                sbb     ax,ss:2[bx]
                mov     ss:2[bx],ax
                mov     ax,cx
                sbb     ax,ss:4[bx]
                mov     ss:4[bx],ax
                mov     ax,cx
                sbb     ax,ss:6[bx]
                mov     ss:6[bx],ax
                ret

idivision       label   near
                mov     ax,x+6[bp]
                test    ax,ax
                jl      x_neg
                mov     ax,y+6[bp]
                test    ax,ax
                jge     x_pos_y_pos
                lea     bx,y[bp]
                call    negate
                call    division        ; +ve / -ve = -ve rem +ve
                and     word ptr what_reqd[bp],2
                jmp     neg_both
x_neg:          mov     ax,y+6[bp]
                test    ax,ax
                jl      x_neg_y_neg
                lea     bx,x[bp]
                call    negate
                call    division        ; -ve / +ve = -ve rem -ve
                jmp     neg_both
x_neg_y_neg:    lea     bx,x[bp]
                call    negate
                lea     bx,y[bp]
                call    negate
                call    division        ; -ve / -ve = +ve rem -ve
                and     word ptr what_reqd[bp],1
                jmp     neg_both
x_pos_y_pos:    call    division        ; +ve / +ve = +ve rem +ve
                jmp     idiv_ret
neg_both        label   near
neg_quot:       test    word ptr what_reqd[bp],2
                je      neg_rem
                lea     bx,q[bp]
                call    negate
neg_rem:        test    word ptr what_reqd[bp],1
                je      idiv_ret
                lea     bx,r[bp]
                call    negate
idiv_ret:       ret

division        label   near
                push    si
                push    di
                lea     bx,y[bp]
                call    _length
                cmp     al,1
                jne     di_y_not_1
                mov     ax,y[bp]
                lea     di,q[bp]
                lea     si,x[bp]
                call    quotient
                test    byte ptr what_reqd[bp],1
                je      di_done
                lea     bx,r[bp]
                call    zero
                mov     r[bp],dx
                jmp     di_done
di_y_not_1      label   near
                mov     cx,ax
                lea     bx,x[bp]
                call    _length
                cmp     al,cl
                jge     di_x_ge_y
                lea     bx,q[bp]
                call    zero
                test    byte ptr what_reqd[bp],1
                je      di_done
                lea     si,x[bp]
                lea     di,r[bp]
                call    copy
                jmp     di_done
di_x_ge_y       label near
                xor     ch,ch
                mov     ld_m[bp],cx
                xor     ah,ah
                mov     ld_n[bp],ax
                call    longdivision
di_done         label   near
                pop     di
                pop     si
                ret

di_prolog_ss    label   near
                xchg    ax,x+8[bp]
                mov     prolog_save[bp],ax
                xor     ax,ax
                xchg    ax,x+8[bp]
                push    ax
                push    bx
                push    cx
                push    dx              ; x
                push    x+8[bp]
                push    ss:6[si]
                push    ss:4[si]
                push    ss:2[si]
                push    ss:0[si]        ; y
                push    prolog_save[bp]
                ret

di_prolog_es    label   near
                xchg    ax,x+8[bp]
                mov     prolog_save[bp],ax
                xor     ax,ax
                xchg    ax,x+8[bp]
                push    ax
                push    bx
                push    cx
                push    dx              ; x
                push    x+8[bp]
                push    es:6[si]
                push    es:4[si]
                push    es:2[si]
                push    es:0[si]        ; y
                push    prolog_save[bp]
                ret


; u8 / u8
; [dx cx bx ax] __U8DQ [dx cx bx ax] [ss:si]

defp            __U8DQ
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_ss
                mov     word ptr what_reqd[bp],2
                call    division
                lea     sp,q[bp]
                jmp     pop_ret
endproc         __U8DQ

; u8 % u8
; [dx cx bx ax] __U8DR [dx cx bx ax] [ss:si]

defp            __U8DR
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_ss
                mov     word ptr what_reqd[bp],1
                call    division
                lea     sp,r[bp]
                jmp     pop_ret
endproc         __U8DR

; i8 / i8
; [dx cx bx ax] __I8DQ [dx cx bx ax] [ss:si]

defp            __I8DQ
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_ss
                mov     word ptr what_reqd[bp],2
                call    idivision
                lea     sp,q[bp]
pop_ret         label   near
                pop     dx
                pop     cx
                pop     bx
                pop     ax
                mov     sp,bp
                pop     bp
                ret
endproc         __I8DQ

; i8 % i8
; [dx cx bx ax] __I8DR [dx cx bx ax] [ss:si]

defp            __I8DR
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_ss
                mov     word ptr what_reqd[bp],1
                call    idivision
                lea     sp,r[bp]
                jmp     pop_ret
endproc         __I8DR

; u8 / u8
; [dx cx bx ax] __U8DQE [dx cx bx ax] [es:si]

defp            __U8DQE
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_es
                mov     word ptr what_reqd[bp],2
                call    division
                lea     sp,q[bp]
                jmp     pop_ret
endproc         __U8DQE

; u8 % u8
; [dx cx bx ax] __U8DRE [dx cx bx ax] [es:si]

defp            __U8DRE
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_es
                mov     word ptr what_reqd[bp],1
                call    division
                lea     sp,r[bp]
                jmp     pop_ret
endproc         __U8DRE

; i8 / i8
; [dx cx bx ax] __I8DQE [dx cx bx ax] [es:si]

defp            __I8DQE
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_es
                mov     word ptr what_reqd[bp],2
                call    idivision
                lea     sp,q[bp]
                jmp     pop_ret
endproc         __I8DQE

; i8 % i8
; [dx cx bx ax] __I8DRE [dx cx bx ax] [es:si]

defp            __I8DRE
                push    bp
                mov     bp,sp
                lea     sp,amt[bp]
                call    di_prolog_es
                mov     word ptr what_reqd[bp],1
                call    idivision
                lea     sp,r[bp]
                jmp     pop_ret
endproc         __I8DRE


        endmod
        end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?