ASM. Работа со строками

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Sams, 1 Apr 2011.

  1. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Ломаю голову уже не первый день. Хочу сделать не "шопопало", а более-менее оптимизированный алгоритм. Жаль только идей мало в голову лезет. Точнее много, но бредовых.

    В общем ситуация такова. Хочу на ассемблере реализовать некую систему работы с текстовыми строками. Суть заключается в том, что бы зная номер строки, можно было скопировать её из буфера.
    Значит имеется буфер - массив байт, содержащий текст, строки которого разделены 2-мя байтами ASCII кода 13d,10d (в общем обычный текстовый документ).
    У меня появилось 2 варианта:
    1. Передав этот буфер функции, и номер нужной строки, на выходе получим адрес этой строки в буфере и её длину,
    2. Аналогично, только передать еще один параметр - выходной буфер, в который сразу будет записан результат, т.е. текстовая строка (но этот вариант не желателен, т.к. заранее размер строки не известен, а значит и буфер делать надо наугад).

    Меня интересует алгоритм считывания. Каждый раз высчитывать адрес строки от начала буфера - слишком затратно. Если например будет 1 МБ данных, то проверять каждый байт на 13d,10d, потом еще отсчитывать количество строк, пока не достигнуть нужной, и если это где-то в самом конце, то такой процесс думаю будет долгим.
    Еще возникла одна идея, но не могу довести её до конца. Перед работой с буфером вызывать специальную функцию, которая его спрасит, и создаст специальную таблицу, содержащую адреса начала каждой строки и её размер. Тогда что бы получить адрес определенной строки не нужно будет каждый раз заново побайтно парсить буфер, а просто извлечь из этой таблицы.

    Может лучше всё это дело реализовать через WinAPI? Но какие функции тут смогут помочь?
    В общем кто что скажет по этому поводу? Как лучше поступить?
     
    #1 Sams, 1 Apr 2011
    Last edited: 1 Apr 2011
  2. 0xF0RD

    0xF0RD Member

    Joined:
    2 Dec 2009
    Messages:
    49
    Likes Received:
    6
    Reputations:
    0
    Вот, на скорую руку набросал, думаю, разберешься))
    Компилятор MASM
    Code:
    ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        include \masm32\include\masm32rt.inc
    ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
    comment * -----------------------------------------------------
                         Build this console app with
                      "MAKEIT.BAT" on the PROJECT menu.
            ----------------------------------------------------- *
    
        .data?
          value dd ?
    
        .data
          table     dd  100 dup (0)
          buff      db  1000 dup (0)
          text      db  "Информация о внесении изменений в настоящий документ содержится в документе:",13,10
                    db  "Федеральный закон от 25 декабря 2008 г. N 280-ФЗ О внесении изменений в",13,10
                    db  "отдельные законодательные акты Российской Федерации в связи с ратификацией",13,10
                    db  "Конвенции Организации Объединенных Наций против коррупции от 31 октября 2003 года",13,10
                    db  "и Конвенции об уголовной ответственности за коррупцию от 27 января 1999 года и",13,10
                    db  "принятием Федерального закона О противодействии коррупции",13,10
                    db  "Принят Государственной Думой 6 марта 1998 года Одобрен Советом Федерации 12 марта 1998 года",13,10
                    db  "См. План мероприятий Правительства РФ по реализации настоящего Федерального закона, утвержденный распоряжением Правительства РФ от 28 июля 1998 г. N 1017-р",13,10
                    db  "См. комментарий к настоящему Федеральному закону",13,10
                    db  "Федеральным законом от 11 ноября 2003 г. N 141-ФЗ в преамбулу настоящего",13,10
                    db  "Федерального закона внесены изменения См. текст преамбулы в предыдущей редакции",13,10
                    db  "Настоящий Федеральный закон в соответствии с Конституцией Российской Федерации",13,10
                    db  "определяет права, свободы, обязанности и ответственность военнослужащих, а также",13,10
                    db  "              ",13,10
                    db  " ",13,10
        endtext     dd  0,0   
    ;**********************************
    
    .code
    ;Процедура заполняет таблицу адресами начала строк из буфера
    ;Длина строки вычисляется как разность между двумя соседними адресами.))
    FillArray   proc
            push    edi
            xor     eax,eax
            repne   scasb
            mov     esi, edi
            pop     edi
            mov     edx, offset table
    l0:     mov     ecx,100h
            mov     [edx], edi
            add     edx,4
            mov     ax, 0Dh
            repne   scasb
            inc     edi
            cmp     edi,esi
            jl      l0
            retn        
    FillArray   endp
    
    ;******************************
    ;******************************
    start:
            mov     edi, offset text    ;Наш текст
            call    FillArray
            mov     ecx,4
            dec     ecx
            mov     esi, offset table   ;Таблица смещений начала строк
            mov     ebx,[esi+ecx*4]
            mov     ecx,[esi+ecx*4+4]         
            push    ebx
            pop     esi
            sub     ecx,ebx
            mov     edi, offset buff;   Куда копировать строку
    l1:     lodsb
            stosb
            dec     ecx
            jnz     l1
            invoke  ExitProcess, 0
    end start
    
     
    #2 0xF0RD, 2 Apr 2011
    Last edited: 2 Apr 2011
    1 person likes this.
  3. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Вообще я хотел узнать мнение по поводу своего алгоритма да и оптимизации работы со строками. Значит всё таки с таблицами я не плохо придумал.

    Отлично.

    Спасибо конечно за код, но в частности за
    А я хотел хранить длину строки в таблице, тем самым увеличив ее размер. Ну да, извлечь 2 соседних адреса и найти между ними разницу + сделать 2 декремента, что бы получить чистую строку, значительно оптимизированиние с точки зрения экономии места, да и вычислительных действий по минимуму, что выполниться за доли секунды. Это отлично дополняет идею с таблицами :)
    Вот за это отдельное спасибо.

    Если честно, я думал что вообще никто не откликнется :D

    Кто может еще предложить какой-либо алгоритм? (хотя в принципе я думаю с таблицей идеально подходит)
     
    #3 Sams, 2 Apr 2011
    Last edited: 2 Apr 2011