Ломаю голову уже не первый день. Хочу сделать не "шопопало", а более-менее оптимизированный алгоритм. Жаль только идей мало в голову лезет. Точнее много, но бредовых. В общем ситуация такова. Хочу на ассемблере реализовать некую систему работы с текстовыми строками. Суть заключается в том, что бы зная номер строки, можно было скопировать её из буфера. Значит имеется буфер - массив байт, содержащий текст, строки которого разделены 2-мя байтами ASCII кода 13d,10d (в общем обычный текстовый документ). У меня появилось 2 варианта: 1. Передав этот буфер функции, и номер нужной строки, на выходе получим адрес этой строки в буфере и её длину, 2. Аналогично, только передать еще один параметр - выходной буфер, в который сразу будет записан результат, т.е. текстовая строка (но этот вариант не желателен, т.к. заранее размер строки не известен, а значит и буфер делать надо наугад). Меня интересует алгоритм считывания. Каждый раз высчитывать адрес строки от начала буфера - слишком затратно. Если например будет 1 МБ данных, то проверять каждый байт на 13d,10d, потом еще отсчитывать количество строк, пока не достигнуть нужной, и если это где-то в самом конце, то такой процесс думаю будет долгим. Еще возникла одна идея, но не могу довести её до конца. Перед работой с буфером вызывать специальную функцию, которая его спрасит, и создаст специальную таблицу, содержащую адреса начала каждой строки и её размер. Тогда что бы получить адрес определенной строки не нужно будет каждый раз заново побайтно парсить буфер, а просто извлечь из этой таблицы. Может лучше всё это дело реализовать через WinAPI? Но какие функции тут смогут помочь? В общем кто что скажет по этому поводу? Как лучше поступить?
Вот, на скорую руку набросал, думаю, разберешься)) Компилятор 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 соседних адреса и найти между ними разницу + сделать 2 декремента, что бы получить чистую строку, значительно оптимизированиние с точки зрения экономии места, да и вычислительных действий по минимуму, что выполниться за доли секунды. Это отлично дополняет идею с таблицами Вот за это отдельное спасибо. Если честно, я думал что вообще никто не откликнется Кто может еще предложить какой-либо алгоритм? (хотя в принципе я думаю с таблицей идеально подходит)