Category : C Source Code
Archive   : PGP20SRC.ZIP
Filename : 8086.ASM

 
Output of file : 8086.ASM contained in archive : PGP20SRC.ZIP
; Assembly primitives for RSA multiprecision library
;
; Tested with Turbo Assembler 1.0 and masm 1.00
;
; Written by Branko Lankester ([email protected]) 10/10/91

; define LDATA and LCODE as follows:
; model: small compact medium large
; LDATA 0 1 0 1
; LCODE 0 0 1 1

LDATA equ 1
LCODE equ 1

IF LDATA
DSTPTR equ es:[bx+si]
ELSE
DSTPTR equ [bx+si]
ENDIF

IF LCODE
prec equ [bp+6] ; 1st arg
r1 equ [bp+6] ; 1st arg
IF LDATA
r2 equ [bp+10] ; 2nd arg
carry equ [bp+14] ; 3rd arg
scarry equ [bp+10] ; carry for shift (arg 2)
ELSE
r2 equ [bp+8]
carry equ [bp+10]
scarry equ [bp+8]
ENDIF
ELSE ; small code model
prec equ [bp+4]
r1 equ [bp+4]
IF LDATA
r2 equ [bp+8]
carry equ [bp+12]
scarry equ [bp+8]
ELSE
r2 equ [bp+6]
carry equ [bp+8]
scarry equ [bp+6]
ENDIF
ENDIF


_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP
_TEXT ends

_DATA segment word public 'DATA'
_DATA ends

_BSS segment word public 'BSS'
prec16 dw ? ; precision / 16 (seems to be / 256?)
unitprec dw ? ; precision / 16, really
addp dw ? ; jump offset
subp dw ?
rotp dw ?
mulp dw ?
_BSS ends

_TEXT segment byte public 'CODE'

public _P_SETP
public _P_ADDC
public _P_SUBB
public _P_ROTL

IF LCODE
fprims proc far ; dummy proc
ELSE
fprims proc near
ENDIF

;
; ******************** set precision ********************
;
_P_SETP:
push bp
mov bp,sp
mov ax, prec ; precision in bits
add ax, 0fh
mov cl,4
shr ax,cl ; prec. in units

mov unitprec,ax
push ax
shr ax,cl
mov prec16,ax ; precision / 16
pop ax
and ax,0fh ; al = prec % 16
mov bx,ax
mov cx,ax
shl bx,1 ; multiply by 4 (=number of bytes
shl bx,1 ; in instruction sequence)
mov dx,bx
IFE LDATA
sub dx,ax ; small model only 3 for add/sub
ENDIF
mov ax,offset add_ref
sub ax,dx
mov addp,ax

mov ax,offset sub_ref
sub ax,dx
mov subp,ax

mov ax,offset rot_ref
sub ax,bx
mov rotp,ax

mov ax,offset mul_ref
shl bx,1 ; MULU macro is 17 bytes for large data
shl bx,1
sub ax,bx
sub ax,cx
mov mulp,ax

pop bp
ret



;
; ******************** mpi add with carry ********************
;
ADDU macro n
rept n
lodsw
adc DSTPTR,ax
endm
endm


_P_ADDC:
push bp
mov bp,sp
push si
mov cx, prec16
mov dx, addp
IF LDATA
push ds
lds si, dword ptr r2
les bx, dword ptr r1
ELSE
mov si, r2
mov bx, r1
ENDIF
sub bx, si ; calculate relative offset
dec bx
dec bx
cld
shr byte ptr carry,1 ; load carry
jcxz add_units
add_16u:
ADDU 16
loop add_16u
add_units:
jmp dx
ADDU 15
add_ref:
rcl ax,1 ; return carry
and ax,1
IF LDATA
pop ds
ENDIF
pop si
pop bp
ret



;
; ******************** mpi subtract with borrow ********************
;
SUBU macro n
rept n
lodsw
sbb DSTPTR,ax
endm
endm


_P_SUBB:
push bp
mov bp,sp
push si
mov cx, prec16
mov dx, subp
IF LDATA
push ds
lds si, dword ptr r2
les bx, dword ptr r1
ELSE
mov si, r2
mov bx, r1
ENDIF
sub bx, si ; calculate relative offset
dec bx
dec bx
cld
shr byte ptr carry,1
jcxz sub_units
sub_16u:
SUBU 16
loop sub_16u
sub_units:
jmp dx
SUBU 15
sub_ref:
rcl ax,1 ; return carry
and ax,1
IF LDATA
pop ds
ENDIF
pop si
pop bp
ret



;
; ******************** mpi rotate left ********************
;
_P_ROTL:
push bp
mov bp,sp
mov cx, prec16
mov dx, rotp
IF LDATA
push ds

lds bx, dword ptr r1
ELSE
mov bx, r1
ENDIF
shr byte ptr scarry,1
jcxz rot_units
rot_16u:
i = 0
rept 16
rcl word ptr [bx + i],1
i = i + 2
endm
lahf
add bx,32
sahf
loop rot_16u
rot_units:
jmp dx
rept 15
rcl word ptr [bx],1
inc bx
inc bx
endm
rot_ref:

rcl ax,1
and ax,1
IF LDATA
pop ds
ENDIF
pop bp
ret

fprims endp

_TEXT ends



; ***************************************************************
; P_SMUL (MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier)
; mp_smul routine from Upton's modmult, converted to assembler
;
; Multiply the single-word multiplier times the multiprecision integer
; in multiplicand, accumulating result in prod. The resulting
; multiprecision prod will be 1 word longer than the multiplicand.
; multiplicand is unit_prec words long. We add into prod, so caller
; should zero it out first.
;
; NOTE: Unlike other functions in the multiprecision arithmetic
; library, both multiplicand and prod are pointing at the LSB,
; regardless of byte order of the machine. On an 80x86, this makes
; no difference. But if this assembly function is implemented
; on a 680x0, it becomes important.
; ***************************************************************
; Variable assignments:
; multiplier = [bp+14]
; multiplicand = [ds:di] 32-bit pointer
; prod = [es:si] 32-bit pointer
; unit_prec = cx
; p = ax-dx
; carry = bx
UPTON_TEXT SEGMENT WORD PUBLIC 'CODE'
UPTON_TEXT ENDS
UPTON_TEXT SEGMENT
ASSUME CS: UPTON_TEXT
ASSUME DS: DGROUP
PUBLIC _P_SMUL

MULU macro n
rept n
lodsw ;multiplicand
mul bp ;multiplier, results (p) to AX/DX
add ax,bx ;carry
adc dx,0
add ax,WORD PTR es:[di]
adc dx,0
mov bx,dx ;carry
stosw
endm
endm

_P_SMUL PROC FAR
push bp
mov bp,sp
push di
push si
push ds
mov cx,prec16
mov ax,mulp
push ax

sub bx,bx ;carry = 0, store in bx

les di,DWORD PTR [bp+6] ;prod in es:di
lds si,DWORD PTR [bp+10] ;multiplicand in ds:si
cld
mov bp,[bp+14]

or cx,cx
jnz mul_16u
jmp mul_units
mul_16u:
MULU 16
dec cx
jz mul_units
jmp mul_16u
mul_units:
pop cx
jmp cx
MULU 15
mul_ref:

; We know that the high-order word of prod will always be 0
mov WORD PTR es:[di],bx ;store carry in prod empty high word

pop ds
pop si
pop di
pop bp
ret

_P_SMUL ENDP
UPTON_TEXT ends
end



  3 Responses to “Category : C Source Code
Archive   : PGP20SRC.ZIP
Filename : 8086.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/