📄 mrmuldv.any
字号:
mov [bx],dx ;store carry
pop si
pop bp ;standard C return
ret
_muldvd2 endP
_TEXT ENDS
END
***********************************************************************
/*
* Turbo C compiler V1.5+, Turbo/Borland C++. Microsoft C/C++
* Uses inline assembly feature
* Generates code identical to above version, and
* can be used instead.
*/
#define ASM _asm
unsigned int muldiv(a,b,c,m,rp)
unsigned int a,b,c,m,*rp;
{
ASM mov ax,a ;/* get a */
ASM mul WORD PTR b ;/* multiply by b */
ASM add ax,c ;/* add c to low word */
ASM adc dx,0h ;/* add carry to high word */
ASM div WORD PTR m ;/* divide by m */
ASM mov bx,rp ;/* get address for remainder */
ASM mov [bx],dx ;/* store remainder */
}
/* Replace last two ASM lines when using large data memory models */
/* ASM les bx, DWORD PTR rp ; get address for remainder */
/* ASM mov WORD PTR es:[bx],dx ; store remainder */
unsigned int muldvm(a,c,m,rp)
unsigned int a,c,m,*rp;
{
ASM mov dx,a ;/* get a */
ASM mov ax,c ;/* add in c to low word */
ASM div WORD PTR m ;/* divide by m */
ASM mov bx,rp ;/* get address for remainder */
ASM mov [bx],dx ;/* store remainder */
}
/* Replace last two ASM lines when using large data memory models */
/* ASM les bx, DWORD PTR rp ; get address for remainder */
/* ASM mov WORD PTR es:[bx],dx ; store remainder */
unsigned int muldvd(a,b,c,rp)
unsigned int a,b,c,*rp;
{
ASM mov ax,a ;/* get a */
ASM mul WORD PTR b ;/* multiply by b */
ASM add ax,c ;/* add c to low word */
ASM adc dx,0h ;/* add carry to high word */
ASM mov bx,rp ;/* get address for remainder */
ASM mov [bx],ax ;/* store remainder */
ASM mov ax,dx
}
/* Replace second and third last lines if using large data memory models */
/* ASM les bx, DWORD PTR rp ; get address for remainder */
/* ASM mov WORD PTR es:[bx],ax ; store remainder */
void muldvd2(a,b,c,rp)
unsigned int a,b,*c,*rp;
{
ASM mov ax,a ;/* get a */
ASM mul WORD PTR b ;/* multiply by b */
ASM mov bx,c
ASM add ax,[bx]
ASM adc dx,0h ;/* add carry to high word */
ASM mov si,rp
ASM add ax,[si]
ASM adc dx,0h
ASM mov [si],ax
ASM mov [bx],dx
}
/* for large memory model ....
ASM mov ax,a ;/* get a */
ASM mul WORD PTR b ;/* multiply by b */
ASM les bx, DWORD PTR c
ASM add ax, WORD PTR es:[bx]
ASM adc dx,0h ;/* add carry to high word */
ASM les si,DWORD PTR rp
ASM add ax,WORD PTR es:[si]
ASM adc dx,0h
ASM mov WORD PTR es:[si],ax
ASM les bx,DWORD PTR c
ASM mov WORD PTR es:[bx],dx
*/
**********************************************************************
;
; IBM-PC-8087 for Microsoft C compiler V4.0+
; with 'mr_utype' defined as 'long' (32 bit). See mirdef.hpc
; This allows IBM-PC XT to look a bit like a 32-bit computer
; (which it isn't). To make use of this option:
;
; (1) Must have 8087 Maths Co-processor (for speed and to hold 64-bit
; intermediate product).
;
; (2) Must use 'ANSI' enhanced type C compiler, e.g. Microsoft V3.0+
; and must use header 'miracl.h' which declares function
; parameter types.
;
; Note: some compilation warnings may be generated - ignore them.
;
; Note: This is NOT, in most cases, faster, but it does allow
; very high precision calculations, e.g. 1000!
;
; Note: No versions of muldvm(), muldvd() or muldvd2() yet written for
; this method.
;
ASSUME CS:_TEXT
_TEXT SEGMENT BYTE PUBLIC 'CODE'
PUBLIC _muldiv
_muldiv PROC NEAR
push si ;standard C linkage
push bp
mov bp,sp
finit ;initialise 8087
fild DWORD PTR [bp+6] ;get a
fimul DWORD PTR [bp+0ah];multiply by b
fiadd DWORD PTR [bp+0eh];add c
fild DWORD PTR [bp+12h];get m
fld st(1) ;duplicate a*b+c on stack
fprem ;get remainder
fist DWORD PTR [bp+0ah];store remainder in b
fsubr st,st(2) ;subtract rem from total
fdiv st,st(1) ;divide by m
fist DWORD PTR [bp+6] ;store quotient in a
wait
mov si,[bp+22] ;get address for remainder
mov ax,[bp+10]
mov dx,[bp+12] ;get remainder
mov [si],ax
mov [si+2],dx ;store remainder
mov ax,[bp+6]
mov dx,[bp+8] ;get quotient in dx:ax
pop bp ;standard C return
pop si
ret
_muldiv endP
_TEXT ENDS
END
**************************************************************************
;
; Intel-80386 pseudo-32 bit version - for Microsoft C V5.0+
; Written for MS macro-assembler V5.0+ by Andrej Sauer
; with 'mr_utype' defined as 'long' (32 bit). See mirdef.hpc
; Same comments apply as above (except for 8087 requirement)
; Note that this version will also work with the latest Zortech and
; Borland 16-bit compilers, specifically Borland C++ V3.1+
;
; For large code models (e.g. medium)
;
; change _TEXT to mrmuldv_TEXT (in three places)
; change NEAR to FAR
; change [bp+4] to [bp+6]
; change [bp+8] to [bp+10]
; change [bp+12] to [bp+14]
; change [bp+16] to [bp+18]
; change [bp+20] to [bp+22]
; etc
;
.386
ASSUME CS:_TEXT
_TEXT SEGMENT USE16 PUBLIC 'CODE'
PUBLIC _muldiv
_muldiv PROC NEAR
push bp ;standard C linkage
mov bp,sp
mov eax,[bp+4] ;get a
mul DWORD PTR [bp+8] ;multiply by b
add eax,DWORD PTR [bp+12] ;add c to low word
adc edx,0h ;add carry to high word
div DWORD PTR [bp+16] ;divide by m
mov bx,WORD PTR [bp+20] ;get address for remainder
mov [bx],edx ;store remainder
shld edx,eax,16 ;shift higher half of quotient
;into lower half of edx
pop bp ;standard C return
ret ;quotient: high bits in dx, lows in ax
_muldiv endP
PUBLIC _muldvm
_muldvm PROC NEAR
push bp ;standard C linkage
mov bp,sp
mov edx,[bp+4] ;get a
mov eax,[bp+8] ;add in c
div DWORD PTR [bp+12] ;divide by m
mov bx,WORD PTR [bp+16] ;get address for remainder
mov [bx],edx ;store remainder
shld edx,eax,16 ;shift higher half of quotient
;into lower half of edx
pop bp ;standard C return
ret ;quotient: high bits in dx, lows in ax
_muldvm endP
PUBLIC _muldvd
_muldvd PROC NEAR
push bp ;standard C linkage
mov bp,sp
mov eax,[bp+4] ;get a
mul DWORD PTR [bp+8] ;multiply by b
add eax,DWORD PTR [bp+12] ;add c to low word
adc edx,0h ;add carry to high word
mov bx,WORD PTR [bp+16] ;get address for remainder
mov [bx],eax ;store remainder
mov eax,edx
shld edx,eax,16 ;shift higher half of quotient
;into lower half of edx
pop bp ;standard C return
ret ;quotient: high bits in dx, lows in ax
_muldvd endP
PUBLIC _muldvd2
_muldvd2 PROC NEAR
push bp ;standard C linkage
mov bp,sp
push si
mov eax,[bp+4] ;get a
mul DWORD PTR [bp+8] ;multiply by b
les bx,DWORD PTR [bp+12]
add eax,DWORD PTR es:[bx]
adc edx,0h ;add carry to high word
les si,DWORD PTR [bp+16]
add eax,DWORD PTR es:[si]
adc edx,0h ;add carry to high word
mov DWORD PTR es:[si],eax ;store remainder
les bx,DWORD PTR [bp+12]
mov DWORD PTR es:[bx],edx
pop si
pop bp ;standard C return
ret
_muldvd2 endP
_TEXT ENDS
END
***********************************************************************
;
; Large Memory model version of the above. Useful
; for creating 16-bit DLL on 386+. Microsoft/Borland compatible
;
.386
ASSUME CS:mrmuldv_TEXT
mrmuldv_TEXT SEGMENT USE16 PUBLIC 'CODE'
PUBLIC _muldiv
_muldiv PROC FAR
push bp ;standard C linkage
mov bp,sp
mov eax,[bp+6] ;get a
mul DWORD PTR [bp+10] ;multiply by b
add eax,DWORD PTR [bp+14] ;add c to low word
adc edx,0h ;add carry to high word
div DWORD PTR [bp+18] ;divide by m
les bx,DWORD PTR [bp+22]
mov DWORD PTR es:[bx],edx
shld edx,eax,16 ;shift higher half of quotient
;into lower half of edx
pop bp ;standard C return
ret ;quotient: high bits in dx, lows in ax
_muldiv endP
PUBLIC _muldvm
_muldvm PROC FAR
push bp ;standard C linkage
mov bp,sp
mov edx,[bp+6] ;get a
mov eax,[bp+10] ;add in c
div DWORD PTR [bp+14] ;divide by m
les bx,DWORD PTR [bp+18]
mov DWORD PTR es:[bx],edx
shld edx,eax,16 ;shift higher half of quotient
;into lower half of edx
pop bp ;standard C return
ret ;quotient: high bits in dx, lows in ax
_muldvm endP
PUBLIC _muldvd
_muldvd PROC FAR
push bp ;standard C linkage
mov bp,sp
mov eax,[bp+6] ;get a
mul DWORD PTR [bp+10] ;multiply by b
add eax,DWORD PTR [bp+14] ;add c to low word
adc edx,0h ;add carry to high word
les bx,DWORD PTR [bp+18]
mov DWORD PTR es:[bx],eax
mov eax,edx
shld edx,eax,16 ;shift higher half of quotient
;into lower half of edx
pop bp ;standard C return
ret ;quotient: high bits in dx, lows in ax
_muldvd endP
PUBLIC _muldvd2
_muldvd2 PROC FAR
push bp ;standard C linkage
mov bp,sp
push si
mov eax,[bp+6] ;get a
mul DWORD PTR [bp+10] ;multiply by b
les bx,DWORD PTR [bp+14]
add eax,DWORD PTR es:[bx]
adc edx,0h ;add carry to high word
les si,DWORD PTR [bp+18]
add eax,DWORD PTR es:[si]
adc edx,0h ;add carry to high word
mov DWORD PTR es:[si],eax
les bx,DWORD PTR [bp+14]
mov DWORD PTR es:[bx],edx
pop si
pop bp ;standard C return
ret
_muldvd2 endP
mrmuldv_TEXT ENDS
END
****************************************************************************
/*
Borland in-line pseudo-32 bit version of the above
Large memory model version.
Use with mirdef.hpc
Unfortunately this cannot be used with Microsoft C,
as its 16 bit compiler will not allow inline 386 opcodes
*/
#define ASM _asm
long muldiv(a,b,c,m,rp)
long a,b,c,m,*rp;
{
ASM mov eax,DWORD PTR a
ASM mul DWORD PTR b
ASM add eax,DWORD PTR c
ASM adc edx,0h
ASM div DWORD PTR m
ASM les bx,DWORD PTR rp
ASM mov DWORD PTR es:[bx],edx
ASM shld edx,eax,16
}
long muldvm(a,c,m,rp)
long a,c,m,*rp;
{
ASM mov edx,DWORD PTR a
ASM mov eax,DWORD PTR c
ASM div DWORD PTR m
ASM les bx,DWORD PTR rp
ASM mov DWORD PTR es:[bx],edx
ASM shld edx,eax,16
}
long muldvd(a,b,c,rp)
long a,b,c,*rp;
{
ASM mov eax,DWORD PTR a
ASM mul DWORD PTR b
ASM add eax,DWORD PTR c
ASM adc edx,0h
ASM les bx,DWORD PTR rp
ASM mov DWORD PTR es:[bx],eax
ASM mov eax,edx
ASM shld edx,eax,16
}
void muldvd2(a,b,c,rp)
long a,b,*c,*rp;
{
ASM mov eax,DWORD PTR a
ASM mul DWORD PTR b
ASM les bx,DWORD PTR c
ASM add eax,DWORD PTR es:[bx]
ASM adc edx,0h
ASM les si,DWORD PTR rp
ASM add eax,DWORD PTR es:[si]
ASM adc edx,0h
ASM mov DWORD PTR es:[si],eax
ASM les bx,DWORD PTR c
ASM mov DWORD PTR es:[bx],edx
}
***********************************************************************
/*
* Borland C++ 32-bit compiler (BCC32). Use with mirdef.h32
* Uses inline assembly feature. Suitable for Win32 Apps
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -