;Открывает файл и читает из него строку в буфер
include 'win32ax.inc'
.data
bytesread dd ?
byteswritten dd ?
filelength dq ?
handle dd ?
habdle2 dd ? ; дескриптор второго файла
s db 250 dup(0) ; строка с массивом чисел, которую нужно распознать
slength = $-s ; 250
slen db ? ; длина входной строки
buf db 10 dup(0) ; буфер для записи одного числа входной строки
bufsize db 0 ; количество записанных символов в буфер
array db 100 dup(0) ; массив, в который записываются числа из входной строки
arraylen db 0 ; количество элементов в массиве array
radix db 10 ; основание системы счисления
subarray db 50 dup(0) ; подмассив в виде строки
subalen db 0 ; длина этой строки
result db 250 dup(0) ; результат, который записывается в файл
reslen dd 0
number db 3 ; заданное число
buffer rb 10
tmp db '-', 0
.code
start:
invoke CreateFile, 'text1.txt', GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
mov [handle], eax
invoke GetFileSize, [handle], filelength
invoke ReadFile, [handle], s, slength, bytesread, NULL
invoke CloseHandle, [handle]
;=============================================================================================;
mov eax, [bytesread]
;dec eax ; не учитываем нулевой символ в конце строки
mov [slen], al
xor ecx, ecx
mov cl, [slen] ; записываем в ECX длину входной строки
inc cl
xor esi, esi
mov esi, s ; записываем в ESI указатель на начало строки (текущий элемент входной строки)
mov edi, buf
mov ebx, array
; перебираем все символы входной строки
.m1:
; если текущий символ - пробел или 0, то конвертируем
cmp [esi], byte ' '
je .convert
cmp [esi], byte 0
je .convert
; если текущий символ - не пробел и не 0
; то дописываем текущий символ в буфер
mov al, [esi]
mov [edi], al
inc [bufsize]
inc edi
jmp .continue
; конвертирует число из строки и дописывает его в конец массива arr
.convert:
;push ecx
;invoke MessageBox, 0, buf, Caption, MB_OK
;pop ecx
xor eax, eax
call StrToInt
; записываем число из eax в конец массива array
mov [ebx], al
inc ebx
mov [bufsize], 0
mov edi, buf
.continue:
inc esi
loop .m1
; сохраняем длину массива array в arraylen
xor ecx, ecx
mov ecx, ebx
sub ecx, array
mov [arraylen], cl
;; выводим массив array (для отладки)
; xor esi, esi
; mov esi, array
; .m2:
; xor eax, eax
; mov al, [esi]
; mov edi, buffer
; call IntToStr
;
; push ecx
; invoke MessageBox, 0, buffer, Caption, MB_OK
; pop ecx
; inc esi
; loop .m2
;=============================================================================================;
;; Сохраняем нужные подпоследовательности в файл
xor ecx, ecx
mov cl, [arraylen]
sub cl, 4 ; записываем в ecx количество подмассивов = arraylen - 5 + 1
xor ebx, ebx ; индекс начала подмассива
;; перебираем все подмассивы
.brute:
;; проверим, содержит ли подмассив, начинающийся с индекса ebx, заданное число
push ecx
xor ecx, ecx
mov cl, 5
mov esi, array
add esi, ebx
.find:
; сравниваем число и значение элемента массива
xor eax, eax
mov al, [number]
cmp al, [esi]
; если находим одинаковые, то выводим этот подмассив
je .print_queue
inc esi
loop .find
pop ecx
jmp .ext
; записываем этот подмассив в файл
.print_queue:
pop ecx
push ecx
xor ecx, ecx
mov cl, 5
mov esi, array
add esi, ebx ; указываем esi на начало текущего подмассива подмассива
; конвертируем этот подмассив в строку subarray
.print:
xor eax, eax
mov al, [esi] ; записываем в al текущее число из подмассива
inc esi ; указываем esi на следующее число
; находим в subarray конец строки и указываем на него edi
mov edi, subarray
.find_zero:
cmp [edi], byte 0
je .zero_found
inc edi
jmp .find_zero
.zero_found:
; записываем пробел:
mov [edi], byte ' '
inc edi
; после пробела записываем число
call IntToStr
loop .print
; определяем длину строки
xor eax, edi
sub eax, subarray
mov [subalen], al
; приписываем subarray к result
pusha
mov esi, result
add esi, [reslen]
mov edi, subarray
.find_finish:
cmp [edi], byte 0
je .finish_found
xor eax, eax
mov al, [edi]
mov [esi], al
inc edi
inc esi
inc [reslen]
jmp .find_finish
.finish_found:
mov [esi], byte 10 ; дописываем символ перевода строки
inc esi
inc [reslen]
mov [esi], byte 0 ; дописываем символ конца строки
invoke MessageBox, 0, result, 'Лабораторная работа №6', MB_OK
popa
; заполняем subarray нулями
push ecx
xor ecx, ecx
mov cl, 50
mov edi, subarray
.clear:
mov [edi], byte 0
inc edi
loop .clear
pop ecx
pop ecx
.ext:
inc ebx
cmp cl, byte 0
dec cl
jne .brute
;loop .brute
;; непосредственно запись результата в файл
; создаём файл
invoke CreateFile, 'text2.txt', GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
; сохраняем дескриптор
mov [handle], eax
; сохраняем в созданный файл массив result
invoke WriteFile, [handle], result, [reslen], byteswritten, 0
; закрываем файл
invoke CloseHandle, [handle]
; вывод сообщения об успехе
invoke MessageBox, 0, 'Файл успешно сохранён!', 'Лабораторная работа №6', MB_OK
; invoke MessageBox, 0, s, 'Lab6', MB_OK
invoke ExitProcess, 0
;=============================================================================================;
;; конвертирует число из строки, записанной в buf в eax
proc StrToInt
; сохраняем в стек используемые регистры
push ecx esi
mov esi, buf
mov cl, [bufsize]
xor eax, eax ; eax = 0
; перебираем все элементы строки
.m:
mul [radix] ; eax = eax * 10
mov dl, [esi] ; eax = eax * 10 + s[i]
sub dl, byte '0' ; eax = eax * 10 + s[i] - 0
add al,dl
inc esi
loop .m
; восстанавливаем из стека используемые регистры
pop esi ecx
ret
endp
;=============================================================================================;
IntToStr:
;eax = number, ebx = base(основание системы счисления=10), edi = buffer(буфер для хранения строки ;результата)
pusha
cmp eax,0
jnl not_neg
neg eax
mov [edi], byte '-'
inc edi
not_neg:
xor ecx,ecx
mov ebx, 10
.new:
xor edx,edx
div ebx
push edx
inc ecx
test eax,eax
jnz .new
.loop:
pop eax
add al, 30h
mov [edi], al
inc edi
loop .loop
mov al, 0
mov [edi],al
popa
ret
.end start