home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
basic
/
compiler
/
ubasic
/
ubmpqs32
/
mpqshd4.asm
< prev
next >
Wrap
Assembly Source File
|
1990-08-05
|
18KB
|
1,177 lines
;MPQSHD4.ASM 3.2
; MACHINE LANGUAGE SUBROUTINE
; FOR MULTIPLE POLYNOMIAL QUADRATIC SIEVE
; hard disk verion
; 1989/90 by YUJI KIDA
;
.386p
code segment use16
assume cs:code,ds:code
org 100h
start:
INCLUDE UBP.MAC
include mpqshd.h
GaussShort macro reg
push cx
and reg,0000ffffh
mov cl,[unitshift]
shl reg,cl
add reg,GaussShortadr
pop cx
endm
GaussMini macro reg
and reg,0000ffffh
add reg,GaussMiniadr
endm
JMP start0
align 4
GaussLongadr dd ?
unitmask dd 0
unitbytes dd 0
unitcolumns dw 0
unitwords dw 0
unitdwords dw 0
unitshift db 0,0
start_column dw ?
current_wordimg dw ?
current_wordptr dw ?
current_row dw ?
start_row dw ?
checking_row dw ?
rank_now dw ?
primes dw ?
matrix_size dw ?
handle dw ?
handle1 dw ?
size1 dw ?
handle2 dw ?
size2 dw ?
handle3 dw ?
size3 dw ?
handle4 dw ?
loadallcount dw ?
work_seg dw ?
ans_seg dw ?
P_OFF dw ?
P_SEG dw ?
primeadrnow dd ?
y_off dw ?
y_seg dw ?
offnow dw ?
refer_adr dd ?
allbytes dw 0,0 ;2nd is a dummy
allwords dw ?
alldwords dw ?
halfbytes dw ?
halfwords dw ?
RWadr dw ?
RWrow dw ?
;üÖüÖ COMMAND é╠ÉUéΦò¬é»
START0:
MOV_AX AR0 ;ARRAY[0] é┼âRâ}âôâhôné╡
MOV BX,OFFSET CMD_TBL
SHL AX,1
ADD BX,AX
JMP CS:[BX]
CMD_TBL:
DW gauss_INIT,GETPRIME,Gauss,CLOSE_FILE
DW SQUARE_ANS,GET_DIV
;
; get and set primes
;
;command#=1
getprime:
lds si,dword ptr cs:[P_OFF]
mov edi,dword ptr cs:[primeadrnow]
lodsw
cmp ax,2
je getprime4B
xor eax,eax
mov ax,[si]
getprime10:
mov fs:[edi],eax
add cs:[primeadrnow],4
mov ax,ss
mov ds,ax
retf
getprime4B:
mov eax,[si]
jmp getprime10
;
;üÖüÖ GaussÅ┴ïÄé╔éµé┴é─ô╛éτéΩé╜ò╜ò√Éöé≡ò╘é╖
; ans#(0) é╔ BIT PATTERN é≡ò╘é╖
;COMMAND#=4
SQUARE_ANS:
mov ax,cs
mov ds,ax
mov es,ax
ans_again:
mov ax,[start_row]
inc ax
mov [start_row],ax
dec ax
cmp ax,[matrix_size]
JAE NO_ANS
mov [RWrow],ax
mov [RWadr],offset buffer1
call load_row
mov si,offset buffer1
mov cx,[halfbytes]
add si,cx ;si = buffer1 + halfbytes
mov di,si
add di,cx ;di = buffer1 + 2*halfbytes - 2
sub di,2 ; = highest word adr
shr cx,1
mov ax,ds
mov es,ax
xor ax,ax
std
repe scasw
cld
je ans_again ;illegal answer
inc cx ;WORDS
mov es,[ans_seg]
xor di,di
MOV AX,CX
STOSW ;attribute
REP MOVSW
ans100:
MOV AX,SS
MOV DS,AX
MOV ES,AX
RETF
NO_ANS:
mov bx,AR0
mov word ptr cs:[bx],0
JMP ANS100
;
;üÖüÖ Y é≡æfê÷Éöò¬ë≡é╡ï╨ÄwÉöé≡ïüé▀éΘ
; completely decomposed if no bug
; COMMAND#=5
; INPUT Y
; OUTPUT WORK%()
GET_DIV:
PUSH BP
LDS SI,DWORD PTR CS:[Y_OFF]
MOV BX,SI ;MEMO èäéτéΩéΘÉö
mov edi,primeadr2+4 ;offset of 2
MOV CS:[OFFNOW],0 ;offset in work%
STD
mov ax,[bx] ;transfer to 32bit format
test al,1
jz gdiv3200 ;if even words
mov si,bx
mov dx,ax
SHL dX,1
add si,dx ;highest adr
mov word ptr [si+2],0
inc ax
gdiv3200:
shr ax,1
mov [bx],ax
MOV CX,CS:[primes]
gdiv32LP:
PUSH CX
MOV eBP,fs:[eDI] ;ebp=èäéΘÉö
add cs:[offnow],2 ;offset in work%
gdiv3210:
MOV SI,BX
MOV AX,[SI]
MOV CX,AX ;dword length
SHL AX,2
sub ax,2
ADD SI,AX ;ì┼Åπê╩
XOR eDX,eDX
gdiv3220:
LODSd
DIV eBP
LOOP gdiv3220
OR eDX,eDX
JZ gdiv32100 ;èäéΦÉ╪éΩé╜ÅΩìçé═û{ôûé╔èäéΘ
add edi,4
POP CX
LOOP gdiv32LP
jmp gdivret
gdiv32100:
MOV AX,DS
MOV DS,CS:[work_seg]
MOV SI,CS:[OFFNOW]
INC WORD PTR [SI]
MOV DS,AX
MOV SI,BX
MOV AX,[SI]
MOV CX,AX ;dword length
SHL AX,2
sub ax,2
ADD SI,AX ;ì┼Åπê╩
XOR eDX,eDX
LODSd
DIV eBP
PUSH eAX ;ì┼Åπê╩é╠Æl
JMPS gdiv32120
gdiv32110:
LODSd
DIV eBP
gdiv32120:
MOV [SI+4],eAX
LOOP gdiv32110
POP eAX ;ì┼Åπê╩é╠Æl
OR eAX,eAX
JNZ gdiv32130
mov ax,[bx] ;ì┼Åπê╩é¬ 0 é╚éτé╬ LEN é≡ DEC
dec ax
mov [bx],ax
cmp ax,1
jne gdiv32130
mov eax,[bx+2]
dec eax
jz gdivfin ;already 1
gdiv32130:
JMP gdiv3210
gdivfin:
pop cx ;dummy
gdivout:
POP BP
CLD
MOV AX,SS
MOV DS,AX
MOV ES,AX
RETF
gdivret: ;not enter here if no bug
mov si,bx ;transfer to 16bit format
mov ax,[si]
shl ax,1
mov cx,ax ;word length?
shl ax,1
add si,ax
cmp word ptr [si],0 ;check highest word
jne gdiv32300
dec cx
gdiv32300:
mov [bx],cx
jmp gdivout
;
;üÖüÖ éfé`étérérÅ┴ïÄû@
;
;COMMAND#=2
; eliminate each 128 columns
Gauss:
mov ax,cs
mov ds,ax
mov es,ax
call load_all
call make_unit_matrix_1
mov ax,[current_row]
sub ax,[start_row]
jz gauss_allzero
mov [rank_now],ax
call make_unit_matrix_2
call erase_below
mov ax,[rank_now]
add [start_row],ax
gauss_allzero:
mov ax,[unitcolumns]
sub [start_column],ax
mov ax,ss
mov ds,ax
mov es,ax
retf
erase_below:
mov ax,[start_row]
add ax,[rank_now]
mov [checking_row],ax
mov cx,[matrix_size]
sub cx,ax
mov bx,ax ;[checking_row]
GaussMini ebx
erase_loop:
cmp byte ptr fs:[ebx],0
je erase_below50
push ebx
push cx
mov ax,[checking_row]
mov [RWrow],ax
mov [RWadr],offset BUFFER1
call load_row
call make_xor
mov ax,[checking_row]
mov [RWrow],ax
mov [RWadr],offset BUFFER1
call save_row
pop cx
pop ebx
erase_below50:
inc ebx
inc [checking_row]
loop erase_loop
ret
make_xor:
xor ebx,ebx
mov bx,[start_column]
shr bx,3
and bl,0feh
mov cx,[unitwords]
makexor10:
push cx
mov dx,8000h
makexor15:
test word ptr [BUFFER1+bx],dx
jz makexor60
push dx
xor eax,eax
mov ax,[rank_now]
dec ax
mov edx,dword ptr [allbytes]
mul edx
add eax,GaussLongadr
mov esi,eax
pop dx
makexor20:
test fs:[esi+ebx],dx
jnz makexor25
sub esi,dword ptr [allbytes]
jmp makexor20
makexor25:
xor edi,edi
mov cx,[alldwords]
makexor30:
mov eax,fs:[esi+edi]
xor dword ptr [BUFFER1+di],eax
add edi,4
loop makexor30
makexor60:
shr dx,1
jnc makexor15
sub bx,2
pop cx
loop makexor10
ret
make_unit_matrix_2:
;rewrite RAM matrix by full image
mov [current_row],0
mov ax,[start_column]
shr ax,3
and al,0feh
mov [current_wordptr],ax
mov [current_wordimg],8000h
mov cx,[rank_now]
makeunit2_main_loop:
push cx
; check current row
xor eax,eax
mov ax,[current_row]
mov [checking_row],ax
mov edx,dword ptr [allbytes]
mul edx
add eax,GaussLongadr
mov edi,eax
xor ebx,ebx
mov bx,[current_wordptr]
mov ax,[current_wordimg]
test fs:[edi+ebx],ax
jz makeunit2_next_column2 ;all zero
mov ax,[checking_row]
inc ax
mov [checking_row],ax
mov cx,[rank_now]
sub cx,ax ;# of other rows
jz makeunit2_next_column ;already last row
xor eax,eax
mov ax,[current_row]
mov edx,dword ptr [allbytes]
mul edx
add eax,GaussLongadr
mov esi,eax
makeunit2_110:
push cx
add edi,dword ptr [allbytes]
; check next rows
mov ax,[current_wordimg]
test fs:[edi+ebx],ax
jz makeunit2_130 ;skip if 0
; if nonzero then take xor
mov cx,[alldwords]
makeunit2_120:
mov eax,fs:[esi]
xor fs:[edi],eax
add esi,4
add edi,4
loop makeunit2_120
sub esi,dword ptr [allbytes]
sub edi,dword ptr [allbytes]
makeunit2_130:
pop cx
loop makeunit2_110
makeunit2_next_column:
inc [current_row]
ror [current_wordimg],1
jnc makeunit2_190
sub [current_wordptr],2
makeunit2_190:
pop cx
dec cx
jz makeunit2_ret
jmp makeunit2_main_loop
makeunit2_ret:
ret
makeunit2_next_column2:
ror [current_wordimg],1
jnc makeunit2_210
sub [current_wordptr],2
makeunit2_210:
pop cx ;don't dec
jmp makeunit2_main_loop
make_unit_matrix_1:
;rewrite RAM matrix by partial image
mov eax,GaussLongadr
mov [refer_adr],eax
;* eliminate unitbytes*matrix_size
mov ax,[start_row]
mov [current_row],ax
mov ax,[start_column]
shr ax,3
and al,0feh
mov [current_wordptr],ax
mov [current_wordimg],8000h
mov cx,[unitcolumns]
makeunit10:
push cx
; check current row
mov di,[current_row]
mov [checking_row],di
GaussShort edi
mov bx,[current_wordptr]
and ebx,[unitmask]
mov ax,[current_wordimg]
test fs:[ebx+edi],ax
jz makeunit20
mov ax,[current_row] ;current is nonzero
mov [RWrow],ax
mov [RWadr],offset BUFFER2
call load_row
jmp makeunit60
makeunit20:
;search nonzero
mov cx,[matrix_size]
sub cx,[current_row]
dec cx ;# of other rows
makeunit30:
inc [checking_row]
add edi,[unitbytes]
test fs:[ebx+edi],ax
jnz makeunit40 ;found nonzero
loop makeunit30
jmp makeunit_next_column2 ;all zero
makeunit40:
;exchange these two
;exchange files
mov ax,[current_row]
mov [RWrow],ax
mov [RWadr],offset BUFFER1
call load_row
mov ax,[checking_row]
mov [RWrow],ax
mov [RWadr],offset BUFFER2
call load_row
mov ax,[checking_row]
mov [RWrow],ax
mov [RWadr],offset BUFFER1
call save_row
;exchange short works
mov si,[current_row]
GaussShort esi
mov di,[checking_row]
GaussShort edi
mov cx,[unitdwords]
makeunit50:
mov eax,fs:[esi]
xchg eax,fs:[edi]
mov fs:[esi],eax
add esi,4
add edi,4
loop makeunit50
;exchange mini works
mov si,[current_row]
GaussMini esi
mov di,[checking_row]
GaussMini edi
mov al,fs:[esi]
xchg al,fs:[edi]
mov fs:[esi],al
makeunit60:
;* store this row in RAM
mov si,offset BUFFER2
mov edi,[refer_adr]
mov cx,[alldwords]
makeunit65:
lodsd
mov fs:[edi],eax
add edi,4
loop makeunit65
mov [refer_adr],edi
;* erase other rows
mov ax,[checking_row]
inc ax
mov [checking_row],ax
mov cx,[matrix_size]
sub cx,ax ;# of other rows
jz makeunit_next_column ;already last row
mov di,ax
GaussShort edi
mov bx,[current_wordptr]
and ebx,[unitmask]
makeunit110:
push cx
; check next rows
mov ax,[current_wordimg]
test fs:[ebx+edi],ax
jz makeunit130 ;skip if 0
; if nonzero then take xor
mov si,[current_row]
GaussShort esi
mov cx,[unitdwords]
makeunit120:
mov eax,fs:[esi]
xor fs:[edi],eax
add esi,4
add edi,4
loop makeunit120
sub edi,[unitbytes]
makeunit130:
inc [checking_row]
add edi,[unitbytes]
pop cx
loop makeunit110
makeunit_next_column:
inc [current_row]
makeunit_next_column2:
ror [current_wordimg],1
jnc makeunit200
sub [current_wordptr],2
makeunit200:
pop cx
dec cx
jz makeunit1_ret
jmp makeunit10
makeunit1_ret:
ret
;get all rows by unitbytes
load_all:
mov di,[start_row]
GaussShort edi
mov ax,[start_row]
push ax ;*
load_all11:
cmp ax,[size1]
jae load_all12
mov bx,[handle1]
mov [handle],bx
mov ax,[size1]
sub ax,[start_row]
mov [loadallcount],ax
call loadsub
mov ax,[size1]
load_all12:
cmp ax,[size2]
jae load_all13
mov bx,[handle2]
mov [handle],bx
mov bx,ax
sub ax,[size1]
mov [start_row],ax
mov ax,[size2]
sub ax,bx
mov [loadallcount],ax
call loadsub
mov ax,[size2]
load_all13:
cmp ax,[size3]
jae load_all14
mov bx,[handle3]
mov [handle],bx
mov bx,ax
sub ax,[size2]
mov [start_row],ax
mov ax,[size3]
sub ax,bx
mov [loadallcount],ax
call loadsub
mov ax,[size3]
load_all14:
mov bx,[handle4]
mov [handle],bx
mov bx,ax
sub ax,[size3]
mov [start_row],ax
mov ax,[matrix_size]
sub ax,bx
mov [loadallcount],ax
call loadsub
load_all20:
pop [start_row] ;*
;check 0 or non 0, set result in GaussMiniadr
mov si,[start_row]
GaussShort esi
mov di,[start_row]
GaussMini edi
mov cx,[matrix_size]
sub cx,[start_row]
load_all120:
push cx
xor ax,ax
mov cx,[unitwords]
load_all130:
or ax,fs:[esi]
add esi,2
loop load_all130
or al,ah
mov fs:[edi],al
inc edi
pop cx
loop load_all120
ret
loadsub:
push edi
mov ax,[start_row]
mov dx,[allbytes]
mul dx
mov cx,dx
push cx
mov dx,ax ;cx:dx = file ptr
mov ax,[start_column]
shr ax,3
mov cl,[unitshift]
shr ax,cl ;cut lower bits
shl ax,cl ;
add dx,ax
pop cx
adc cx,0
mov ah,42h ;move file ptr
mov al,0 ;absolute
mov bx,[handle]
int 21h
pop edi
mov cx,[loadallcount]
loadsub10:
push cx
push edi
mov ah,3fh
mov bx,[handle]
mov cx,word ptr [unitbytes]
mov dx,offset SHORTBUFFER
int 21h
xor cx,cx
mov dx,[allbytes]
sub dx,word ptr [unitbytes]
mov ah,42h ;move file ptr
mov al,1 ;relative
mov bx,[handle]
int 21h
pop edi
mov si,offset SHORTBUFFER
mov cx,[unitdwords]
loadsub15:
mov eax,[si]
mov fs:[edi],eax
add si,4
add edi,4
loop loadsub15
pop cx
loop loadsub10
ret
load_row:
mov ax,[RWrow]
mov bx,[handle1]
xor dx,dx
cmp ax,[size1]
jb load_row10
mov bx,[handle2]
mov dx,[size1]
cmp ax,[size2]
jb load_row10
mov bx,[handle3]
mov dx,[size2]
cmp ax,[size3]
jb load_row10
mov bx,[handle4]
mov dx,[size3]
load_row10:
mov [handle],bx
sub ax,dx
mov dx,[allbytes]
mul dx
mov cx,dx
mov dx,ax ;cx:dx = file ptr
mov ah,42h ;move file ptr
mov al,0 ;absolute
mov bx,[handle]
int 21h
mov ah,3fh ;read
mov bx,[handle]
mov cx,[allbytes]
mov dx,[RWadr]
int 21h
ret
save_row:
mov ax,[RWrow]
mov bx,[handle1]
xor dx,dx
cmp ax,[size1]
jb save_row10
mov bx,[handle2]
mov dx,[size1]
cmp ax,[size2]
jb save_row10
mov bx,[handle3]
mov dx,[size2]
cmp ax,[size3]
jb save_row10
mov bx,[handle4]
mov dx,[size3]
save_row10:
mov [handle],bx
sub ax,dx
mov dx,[allbytes]
mul dx
mov cx,dx
mov dx,ax ;cx:dx = file ptr
mov ah,42h ;move file ptr
mov al,0 ;absolute
mov bx,[handle]
int 21h
mov ah,40h ;write
mov bx,[handle]
mov cx,[allbytes]
mov dx,[RWadr]
int 21h
ret
;
;* Initialize for Gaussian elimination
;
;COMMAND#=0
;
gauss_init:
;get parameters
mov ax,cs
mov ds,ax
mov es,ax
mov bx,offset mpqshd4end
add bx,15
shr bx,4
add ax,bx
cmp ax,primeseg2
ja lackofmainmemory
MOV BX,V1 ;P é╠ ADDRESS é╠É▌ÆΦ
MOV AX,[BX]
MOV [P_OFF],AX
MOV AX,[BX+2]
MOV [P_SEG],AX
MOV_AX V2+2 ;work%(0) é╠ SEGMENT
ADD AX,ARRAYHEADSEG
MOV [WORK_SEG],AX
MOV_AX V3+2 ;ans#(0) é╠ SEGMENT
ADD AX,ARRAYHEADSEG
MOV [ANS_SEG],AX
MOV BX,V4 ;Y é╠ ADDRESS é╠É▌ÆΦ
MOV AX,[BX]
MOV [Y_OFF],AX
MOV AX,[BX+2]
MOV [Y_SEG],AX
mov_ax AR1
shl ax,1
dec ax
mov [primes],ax
mov [start_column],ax
inc ax
mov [matrix_size],ax
shl ax,1 ;*2
shr ax,3 ;bits -> bytes
mov [allbytes],ax
shr ax,1
mov [halfbytes],ax
mov [allwords],ax
shr ax,1
mov [halfwords],ax
mov [alldwords],ax
mov [start_row],0
mov [primeadrnow],primeadr2
; check extended memories
mov esi,GaussMiniadr-4
mov eax,19510701h
mov edx,00100000h ;1Mbytes
gauss_init100:
add esi,edx
mov fs:[esi],eax
cmp fs:[esi],eax
je gauss_init100
mov eax,esi
sub eax,edx
sub eax,GaussShortadr-4
shl eax,3
xor edx,edx
mov ecx,3
div ecx
xor edx,edx
mov cx,[matrix_size] ;higher already 0
div ecx
mov edx,maxunitcolumns
cmp eax,edx
jae gauss_init140
gauss_init130:
shr dx,1
test ax,dx
jz gauss_init130
gauss_init140:
mov ax,dx
mov [unitcolumns],ax
shr ax,3
mov word ptr [unitbytes],ax
dec ax
mov word ptr [unitmask],ax
inc ax
shr ax,1
mov [unitwords],ax
shr ax,1
mov [unitdwords],ax
mov cx,1
gauss_init150:
inc cx
shr ax,1
jnc gauss_init150
mov [unitshift],cl ;log_2(unitcolumns/8)
mov eax,[unitbytes]
xor ecx,ecx
mov cx,[matrix_size]
mul ecx
add eax,GaussShortadr
mov [GaussLongadr],eax
;open file
mov bx,offset MATRIXNAME1
MOV_AX AR2
or ax,ax
jz gauss_init170
sub bx,2
add al,'@'
mov [bx],al
gauss_init170:
mov dx,bx
mov ah,3dh
mov al,2 ;read/write
int 21h
jc diskerror
mov [handle1],ax
MOV_AX AR3
shl ax,1
mov [size1],ax
mov bx,offset MATRIXNAME2
MOV_AX AR4
or ax,ax
jz gauss_init180
sub bx,2
add al,'@'
mov [bx],al
gauss_init180:
mov dx,bx
mov ah,3dh
mov al,2 ;read/write
int 21h
jc diskerror
mov [handle2],ax
MOV_AX AR5
shl ax,1
add ax,[size1]
mov [size2],ax
mov bx,offset MATRIXNAME3
MOV_AX AR6
or ax,ax
jz gauss_init190
sub bx,2
add al,'@'
mov [bx],al
gauss_init190:
mov dx,bx
mov ah,3dh
mov al,2 ;read/write
int 21h
jc diskerror
mov [handle3],ax
MOV_AX AR7
shl ax,1
add ax,[size2]
mov [size3],ax
mov bx,offset MATRIXNAME4
MOV_AX AR8
or ax,ax
jz gauss_init200
sub bx,2
add al,'@'
mov [bx],al
gauss_init200:
mov dx,bx
mov ah,3dh
mov al,2 ;read/write
int 21h
jc diskerror
mov [handle4],ax
mov ax,[unitcolumns]
gauss_init_out:
mov bx,AR0
mov [bx],ax
mov bx,AR1
mov word ptr [bx],primeseg2-4000h
mov ax,ss
mov ds,ax
mov es,ax
retf
diskerror:
mov ax,8001h ;set -1
jmp gauss_init_out
lackofmainmemory:
xor ax,ax
jmp gauss_init_out
;
; * Close File
; Command# = 2
CLOSE_FILE:
mov ah,3eh
mov bx,cs:[handle1]
int 21h
mov ah,3eh
mov bx,cs:[handle2]
int 21h
mov ah,3eh
mov bx,cs:[handle3]
int 21h
mov ah,3eh
mov bx,cs:[handle4]
int 21h
retf
db ' :'
MATRIXNAME1 db 'MPQSMAT1.UBD',0
db ' :'
MATRIXNAME2 db 'MPQSMAT2.UBD',0
db ' :'
MATRIXNAME3 db 'MPQSMAT3.UBD',0
db ' :'
MATRIXNAME4 db 'MPQSMAT4.UBD',0
align 4
SHORTBUFFER db maxunitbytes dup(0)
align 4
BUFFER1 db maxbuffersize dup(0)
BUFFER2 db maxbuffersize dup(0)
mpqshd4end:
CODE ENDS
END START