Код:
.data
InputFile db "c:\input.dat",0
DPG db "c:\inputD.dat",0
OutputFile db "c:\output.dat",0
hInput dd ?
hDPG dd ?
hOutput dd ?
FileSize dd 2048
OutputFS dd 4096
inbuf dw 1024 dup(?)
DpgBuf dw 1024 dup(?)
outbuf dw 2047 dup(?)
nRead dd ?
nReadA dd ?
nWrote dd ?
T db 0
Shift dw 0 ;Требуется, когда выполняется 2-ая половина свёртки. Сдвиг начальных/конечных элементов
count dw ? ;Position in InBuf
vector dw 12 dup(0) ; for use with MMX [ result | 0 a1 b1 b0 | 0 yz_1 xz_1 x ]
; bytes: 16-------^ 8--------^ 0---------^
TickCount dd 0
; результат = Y conv DPG, где Y и DPG задаются в массивах(берутся из файла), а conv совершает программа
; Результат записывается в файл
;Array DPG is inverted comparatively inbuf ( Function of the array)
.code
start:
invoke CreateFile, addr InputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
mov hInput, eax
invoke CreateFile, addr DPG, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
mov hDPG, eax
invoke CreateFile, addr OutputFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
mov hOutput, eax
invoke ReadFile, hInput, addr inbuf, FileSize, addr nRead, NULL
invoke ReadFile, hDPG, addr DpgBuf, FileSize, addr nReadA, NULL
; measure milliseconds
; invoke GetTickCount
; mov TickCount, eax
; mov ecx, 10000 ; do 10000 for time measuring
mov Shift, 0
;timeloop: ; метка цикла расчёта времени
; push ecx
; convert parameters for use with MMX
mov ecx, 4094; index of DPG, and count of iteration
mov ebx, 0 ;n
lp: ; метка цикла расчёта очередного элемента
mov edx, ebx
add edx, 2
sub dx, Shift
sub dx, Shift
mov count, 0
; Clearing VectorA & VectorB
mov dword ptr vector, 0
mov dword ptr vector[4], 0
mov dword ptr vector[8], 0
mov dword ptr vector[12], 0
loop1: ; метка внутреннего цикла (расчёт всей длины массива)
;First Filling vector Vector is executed
;Then management is sent on Mull, where occurs filling by vector register MM0 and MM1 and their multiplying
.MMX
cmp edx, 2 ; Если остаток =1
jne L0
Last: ; метка занесения в начало Vector множителей х[j] и y[0]
; x[J](J<=N)
push ebx
sub bx, Shift ; Сдвиг в массиве для второй половины свёртки
mov ax, word ptr inbuf[bx]
mov word ptr vector, ax
pop ebx
; y[Last](J+1-Size=>0 or Last=0)
mov ax, 2046
sub ax, Shift
push ebx
mov bx, ax
mov ax, word ptr DpgBuf[bx]
mov word ptr vector[8], ax
pop ebx
sub edx, 2
jmp Mull
L0:
cmp edx, 4 ; Если остаток =2
jne L1
; x[J-1], x[J]
push ebx
sub ebx, 2
sub bx, Shift
mov eax, dword ptr inbuf[ebx]
pop ebx
mov dword ptr vector, eax
; y[1], y[0]
mov ax, 2044
sub ax, Shift
push ebx
mov bx, ax
mov eax, dword ptr DpgBuf[bx]
mov dword ptr vector[8], eax
sub edx, 4
pop ebx
jmp Mull
L1:
cmp edx, 6 ; Если остаток =3
jne L2
; x[J-2], x[J-1]
push ebx
sub ebx, 4
cmp T,1
jne X3
sub bx, Shift
X3:
mov eax, dword ptr inbuf[ebx]
pop ebx
mov dword ptr vector[2], eax
; y[2], y[1]
push ebx
mov ebx, 2042
sub bx, Shift
mov eax, dword ptr DpgBuf[bx]
mov dword ptr vector[10], eax
pop ebx
sub edx, 4
jmp Last
L2: ; если остаток >= 4
; X
xor eax, eax
mov ax, count
add ax, Shift
movq mm0, qword ptr inbuf[eax]
; Y
cmp T, 1 ; Проверяем, дошла ли обработка до середины
jne Y0
mov eax, 0
add ax, count
jmp Y1
Y0:
add eax, ecx
sub eax, 2048
Y1:
movq mm1, qword ptr DpgBuf[eax]
sub edx, 8
add count, 8
jmp MulReg
Mull: ;Mul Label
movq mm0, qword ptr vector[0]
movq mm1, qword ptr vector[8]
MulReg:
pmaddwd mm0, mm1
paddd MM7, MM0
cmp edx, 0
jne loop1
movq mm0, mm7
psrlq mm7, 32
paddd mm0, mm7
movq qword ptr vector[16], mm0
mov dword ptr vector[20], 0 ; clear high dword
movq mm2, qword ptr vector[16]
psrad mm2, 10 ; result = result / 1024
packssdw mm2, mm2 ; convert signed double word to signed word
movq qword ptr vector[16], mm2
mov eax, dword ptr vector[16]
;mov ax, word ptr vector[16]
mov outbuf[ebx], ax
xor eax, eax
;mov ax, word ptr outbuf[ebx]
inc ebx
inc ebx
dec ecx
dec ecx
cmp ecx, 2046 ; Если дошло до половины...
jne I@
mov T, 1
I@:
cmp T, 1
jne I@@
add Shift, 2
I@@:
cmp ecx, 0
jne lp
emms ; restore floating point registers after MMX usage
invoke WriteFile, hOutput, addr outbuf, OutputFS, addr nWrote, NULL
invoke CloseHandle, hInput
invoke CloseHandle, hOutput
invoke CloseHandle, hDPG
invoke ExitProcess, 0
end start