Don't like ads? PRO users don't see any ads ;-)
Guest

nsv

By: a guest on Jun 17th, 2012  |  syntax: ASM (NASM)  |  size: 8.95 KB  |  hits: 31  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. ;Открывает файл и читает из него строку в буфер
  2.  
  3. include 'win32ax.inc'
  4.  
  5. .data
  6.         bytesread dd ?
  7.         byteswritten dd ?
  8.         filelength dq ?
  9.         handle dd ?
  10.         habdle2 dd ?              ; дескриптор второго файла
  11.  
  12.         s db 250 dup(0)           ; строка с массивом чисел, которую нужно распознать
  13.         slength = $-s             ; 250
  14.         slen db ?                 ; длина входной строки
  15.         buf db 10 dup(0)          ; буфер для записи одного числа входной строки
  16.         bufsize db 0              ; количество записанных символов в буфер
  17.         array db 100 dup(0)       ; массив, в который записываются числа из входной строки
  18.         arraylen db 0             ; количество элементов в массиве array
  19.         radix db 10               ; основание системы счисления
  20.  
  21.         subarray db 50 dup(0)     ; подмассив в виде строки
  22.         subalen db 0              ; длина этой строки
  23.  
  24.         result db 250 dup(0)      ; результат, который записывается в файл
  25.         reslen dd 0
  26.  
  27.         number db 3               ; заданное число
  28.  
  29.         buffer rb 10
  30.  
  31.         tmp db '-', 0
  32.  
  33. .code
  34.     start:
  35.         invoke CreateFile, 'text1.txt', GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
  36.         mov [handle], eax
  37.         invoke GetFileSize, [handle], filelength
  38.         invoke ReadFile, [handle], s, slength, bytesread, NULL
  39.         invoke CloseHandle, [handle]
  40.  
  41. ;=============================================================================================;
  42.  
  43.         mov eax, [bytesread]
  44.         ;dec eax           ; не учитываем нулевой символ в конце строки
  45.         mov [slen], al
  46.         xor ecx, ecx
  47.         mov cl, [slen]    ; записываем в ECX длину входной строки
  48.         inc cl
  49.  
  50.         xor esi, esi
  51.         mov esi, s      ; записываем в ESI указатель на начало строки (текущий элемент входной строки)
  52.         mov edi, buf
  53.         mov ebx, array
  54.         ; перебираем все символы входной строки
  55.        .m1:
  56.            ; если текущий символ - пробел или 0, то конвертируем
  57.            cmp [esi], byte ' '
  58.            je .convert
  59.            cmp [esi], byte 0
  60.            je .convert
  61.  
  62.            ; если текущий символ - не пробел и не 0
  63.            ; то дописываем текущий символ в буфер
  64.  
  65.            mov al, [esi]
  66.            mov [edi], al
  67.  
  68.  
  69.            inc [bufsize]
  70.            inc edi
  71.            jmp .continue
  72.  
  73.            ; конвертирует число из строки и дописывает его в конец массива arr
  74.            .convert:
  75.                ;push ecx
  76.                ;invoke MessageBox, 0, buf, Caption, MB_OK
  77.                ;pop ecx
  78.  
  79.                xor eax, eax
  80.  
  81.                call StrToInt
  82.  
  83.  
  84.                ; записываем число из eax в конец массива array
  85.                mov [ebx], al
  86.                inc ebx
  87.  
  88.  
  89.                mov [bufsize], 0
  90.                mov edi, buf
  91.            .continue:
  92.  
  93.                inc esi
  94.  
  95.         loop .m1
  96.  
  97.         ; сохраняем длину массива array в arraylen
  98.         xor ecx, ecx
  99.         mov ecx, ebx
  100.         sub ecx, array
  101.         mov [arraylen], cl
  102.  
  103. ;; выводим массив array (для отладки)
  104. ;        xor esi, esi
  105. ;        mov esi, array
  106. ;       .m2:
  107. ;            xor eax, eax
  108. ;            mov al, [esi]
  109. ;            mov edi, buffer
  110. ;            call IntToStr
  111. ;
  112. ;            push ecx
  113. ;            invoke MessageBox, 0, buffer, Caption, MB_OK
  114. ;            pop ecx
  115. ;           inc esi
  116. ;        loop .m2
  117.  
  118. ;=============================================================================================;
  119.  
  120.         ;; Сохраняем нужные подпоследовательности в файл
  121.  
  122.         xor ecx, ecx
  123.         mov cl, [arraylen]
  124.         sub cl, 4           ; записываем в ecx количество подмассивов = arraylen - 5 + 1
  125.  
  126.         xor ebx, ebx        ; индекс начала подмассива
  127.  
  128.         ;; перебираем все подмассивы
  129.        .brute:
  130.  
  131.              ;; проверим, содержит ли подмассив, начинающийся с индекса ebx, заданное число
  132.              push ecx
  133.  
  134.              xor ecx, ecx
  135.              mov cl, 5
  136.              mov esi, array
  137.              add esi, ebx
  138.             .find:
  139.                   ; сравниваем число и значение элемента массива
  140.  
  141.                   xor eax, eax
  142.                   mov al, [number]
  143.                   cmp al, [esi]
  144.                   ; если находим одинаковые, то выводим этот подмассив
  145.                   je .print_queue
  146.                   inc esi
  147.              loop .find
  148.              pop ecx
  149.              jmp .ext
  150.  
  151.              ; записываем этот подмассив в файл
  152.             .print_queue:
  153.  
  154.  
  155.                   pop ecx
  156.  
  157.                   push ecx
  158.  
  159.                   xor ecx, ecx
  160.                   mov cl, 5
  161.  
  162.                   mov esi, array
  163.                   add esi, ebx        ; указываем esi на начало текущего подмассива подмассива
  164.  
  165.                   ; конвертируем этот подмассив в строку subarray
  166.                  .print:
  167.                       xor eax, eax
  168.                       mov al, [esi]         ; записываем в al текущее число из подмассива
  169.                       inc esi               ; указываем esi на следующее число
  170.  
  171.                       ; находим в subarray конец строки и указываем на него edi
  172.                       mov edi, subarray
  173.                      .find_zero:
  174.                           cmp [edi], byte 0
  175.                           je .zero_found
  176.                           inc edi
  177.                           jmp .find_zero
  178.                      .zero_found:
  179.  
  180.                       ; записываем пробел:
  181.                       mov [edi], byte ' '
  182.                       inc edi
  183.                       ; после пробела записываем число
  184.                       call IntToStr
  185.  
  186.                   loop .print
  187.  
  188.                   ; определяем длину строки
  189.                   xor eax, edi
  190.                   sub eax, subarray
  191.                   mov [subalen], al
  192.  
  193.                   ; приписываем subarray к result
  194.                   pusha
  195.                         mov esi, result
  196.                         add esi, [reslen]
  197.                         mov edi, subarray
  198.                        .find_finish:
  199.                             cmp [edi], byte 0
  200.                             je .finish_found
  201.  
  202.                             xor eax, eax
  203.                             mov al, [edi]
  204.                             mov [esi], al
  205.  
  206.                             inc edi
  207.                             inc esi
  208.                             inc [reslen]
  209.                             jmp .find_finish
  210.                        .finish_found:
  211.  
  212.                         mov [esi], byte 10 ; дописываем символ перевода строки
  213.                         inc esi
  214.                         inc [reslen]
  215.                         mov [esi], byte 0  ; дописываем символ конца строки
  216.  
  217.                         invoke MessageBox, 0, result, 'Лабораторная работа №6', MB_OK
  218.                   popa
  219.  
  220.                   ; заполняем subarray нулями
  221.                   push ecx
  222.                   xor ecx, ecx
  223.                   mov cl, 50
  224.                   mov edi, subarray
  225.                  .clear:
  226.                       mov [edi], byte 0
  227.                       inc edi
  228.                   loop .clear
  229.                   pop ecx
  230.  
  231.                   pop ecx
  232.  
  233.             .ext:
  234.                   inc ebx
  235.  
  236.         cmp cl, byte 0
  237.         dec cl
  238.         jne .brute
  239.         ;loop .brute
  240.  
  241.         ;; непосредственно запись результата в файл
  242.  
  243.         ; создаём файл
  244.         invoke CreateFile, 'text2.txt', GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
  245.         ; сохраняем дескриптор
  246.         mov [handle], eax
  247.  
  248.         ; сохраняем в созданный файл массив result
  249.         invoke WriteFile, [handle], result, [reslen], byteswritten, 0
  250.  
  251.         ; закрываем файл
  252.         invoke CloseHandle, [handle]
  253.  
  254.         ; вывод сообщения об успехе
  255.         invoke MessageBox, 0, 'Файл успешно сохранён!', 'Лабораторная работа №6', MB_OK
  256.  
  257.         ; invoke MessageBox, 0, s, 'Lab6', MB_OK
  258.         invoke ExitProcess, 0
  259.  
  260. ;=============================================================================================;
  261.  
  262.         ;; конвертирует число из строки, записанной в buf в eax
  263.         proc StrToInt
  264.             ; сохраняем в стек используемые регистры
  265.             push ecx esi
  266.  
  267.             mov esi, buf
  268.             mov cl, [bufsize]
  269.             xor eax, eax ; eax = 0
  270.  
  271.             ; перебираем все элементы строки
  272.            .m:
  273.                  mul [radix]                       ; eax = eax * 10
  274.                  mov dl, [esi]                     ; eax = eax * 10 + s[i]
  275.                  sub dl, byte '0'                  ; eax = eax * 10 + s[i] - 0
  276.                  add al,dl
  277.                  inc esi
  278.  
  279.             loop .m
  280.  
  281.             ; восстанавливаем из стека используемые регистры
  282.             pop esi ecx
  283.             ret
  284.         endp
  285.  
  286. ;=============================================================================================;
  287.  
  288.         IntToStr:
  289.         ;eax = number, ebx = base(основание системы счисления=10), edi = buffer(буфер для хранения строки ;результата)
  290.              pusha
  291.              cmp eax,0
  292.              jnl  not_neg
  293.              neg eax
  294.              mov [edi], byte '-'
  295.              inc edi
  296.             not_neg:
  297.              xor     ecx,ecx
  298.              mov     ebx, 10
  299.            .new:
  300.              xor     edx,edx
  301.              div     ebx
  302.              push    edx
  303.              inc     ecx
  304.              test    eax,eax
  305.              jnz     .new
  306.            .loop:
  307.              pop     eax
  308.              add     al, 30h
  309.              mov    [edi], al
  310.              inc    edi
  311.              loop    .loop
  312.              mov    al, 0
  313.              mov    [edi],al
  314.              popa
  315.             ret
  316.  
  317.  
  318.    .end start