FAQ Поиск Пользователи Группы ФотоАльбом  Регистрация Войти и проверить личные сообщения Вход
Ассемблер, массивы, выделение памяти и адресация + Delphi

 
Начать новую тему   Ответить на тему       Список форумов Forum.profintel.ru -> Программерский раздел
Предыдущая тема :: Следующая тема  
Автор Сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 12:51 am    Заголовок сообщения: Ассемблер, массивы, выделение памяти и адресация + Delphi Ответить с цитатой

Возникла проблема. Пишу курсовую на Delphi. Требуется читать строковый файл, парсить его на строки и запихать в массив. Самым очевидным и простым решением для меня является класс TStringList:
Код:

var
  slFile: TStringList;
begin
  slFile := TStringList.Create();
  slFile.LoadFromFile('c:\file.txt');
  ..
  slFile.Free();

Но, немного подумав, решил написать свой строковой класс (для самообразования). Решил писать его исключительно с помощью WinAPI и ассемблерных вставок. Возникла проблема с функцией загрузки текстового файла, парсинга его на строки и запихивание в массив. Итак (проверки правильности выполнения функций убраны):

Код:

const
  pszFile : PChar = 'c:\2.txt';
var
  i: Integer;
  StringsArray: Pointer;
  pBuffer,pTemp,p: Pointer;
  dwFileSizeLow,NumberOfBytesRead,dwStringsArraySize,dwFind: DWORD;
  hFile,hHeap: THandle;
begin
  //Открываем файл
  hFile := CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  //Получаем размер файла
  dwFileSizeLow := GetFileSize(hFile,nil);
  //Хэндл кучи
  hHeap := GetProcessHeap();
  //Динамически выделям память под файл
  pBuffer := HeapAlloc(hHeap,0,dwFileSizeLow);
  //Читем весь файл
  ReadFile(hFile,PAnsiChar(pBuffer)^,dwFileSizeLow,NumberOfBytesRead,0);
  //Закрываем файл
  CloseHandle(hFile);

  //Выделяем 0 (пока 0) байт под массив указателей на строки файла
  StringsArray := HeapAlloc(hHeap,0,0);
  //Размер этого массива
 dwStringsArraySize := 0;
  //Сам парсинг файла решил сделать на ассемблере (также для самообразования)
  asm
  //Для того чтобы распарсить файл на строки нужно найти все байты с значением 10 (#13#10 - окончание строки в текстовых windows файлах)

    @next:
    mov edi,pBuffer //Адрес строки исчтоника (цепочки байтов)
    mov eax,10 //Ищем байт со значением 10
    mov ecx,NumberOfBytesRead //Количество байт в цепочке
    cld //Ищем с начала строки
    repne scasb //Сканируем цепочку байтов
    //В регистре edi у нас адрес байта в цепочке, который равен 10

    sub edi,pBuffer //Вычитаем адрес этого байта из адреса начала цепочки, чтобы узнать количество символов в строке
    sub NumberOfBytesRead,edi //Уменьшаем длину цепочки
    sub edi,2 //Вычитаем из регистра edi еще 2 байта (#13#10)
    mov dwFind,edi //Копируем длину строки (без байт окончания строки во временную переменную)

    inc dwStringsArraySize //Увеличиваем на 1 размер массива строк
    push 4
    push StringsArray
    push 0
    push hHeap
    call HeapReAlloc //Увеличиваем размер выделенной массиву памяти на 4 байта (размер указателя)
    //Насколько я понимаю, при HeapReAlloc адрес выделяемой памяти не меняется, а лишь увеличивается ее размер
    //Если невозможно выделить участок памяти такого размера - функция HeapReAlloc возвращает ошибку

    mov eax,dwFind //Переносим в регистр eax длину строки
    inc eax //Увеличиваем ее на 1, т.к. добавится символ окончания строки #0
    push eax
    push 0
    push hHeap
    call HeapAlloc  //Выделяем память под эту строку
    mov pTemp,eax  //Переносим адрес выделенного под строку участка памяти во временную переменную

    //Копируем из цепочки строку
    mov esi,pBuffer //адрес начала строки в цепочке
    mov edi,pTemp //адрес выделенного участка памяти
    mov ecx,dwFind //Количество копируемых символов
    cld  //Копируем с начала строки
    rep movsb //Копируем побайтово

    //вызываем мессейжд для проверки "толи скопировалось в буфер"

    push 0
    push 0
    push pTemp
    push 0
    call MessageBox
   
   
    mov eax,edi //Переносим в регистр eax адрес последнеднего скопированного символа
    inc eax  //Увеличиваем его на 1
    mov [eax],0  //Записываем байт со значем 0 - символ окончания строки


    //Тут начинаются непонятки и сложности
    //Насколько я знаю, массив распологается в памяти примерно так:
    //Массив StringsArray является массивом указателей на строки - аналог char **arr в Си
    //Массив состоит из элементов по 4 байта - размер указателя (адреса памяти)
    //Первый (нулевой) элемент массива имеет адрес такой же как и адрес начала всего массива

    mov eax,4
    mul eax,dwStringsArraySize //Вычисляем смещение элемента массива (указателя на строку) в массиве
    sub eax,4
    mov ebx,eax
    add eax,StringsArray //В регистре eax адрес элемента массива


    mov ecx,pTemp //В регистре ecx адрес выделенной памяти (и скопированной туда строки)
    mov [eax],ecx  //Копируем адрес скопированной туда строки по адресу первого элемента массива StringsArray
    //т.е по сути (если я правильно понимаю) делаем следующее - *(StringsArray+(dwStringsArraySize*4)-4) = pTemp

   
    mov eax,dwFind
    add pBuffer,eax
    add pBuffer,2 //Увеличиваем адрес цепочки на размер скопированной строки + символы окончания строки #13#10

    cmp NumberOfBytesRead,0
    je @exit

    jmp @next
    @exit:
  end;
  //Освобождаем память
  HeapFree(hHeap,0,pBuffer);

  //добавил другую проверку  - уже видны ошибки - памяти выделяется не столько, сколько надо
  for i := 0 to dwStringsArraySize-1 do begin
    MessageBox(0,PChar(IntToStr(HeapSize(hHeap,0,Pointer(Integer(StringsArray)+i*4)))),'',0);
  end;

  //Получем не то, что хотели - выводится первая строка, потом она же, но со смещением начала на 4 байта, и т.д...
  //А хотелось бы получить сначала первую строку массива, затем вторую и т.д
  //Грабли или в копировании указателей на строки в массив (копирую не то, не туда) или в вычислении адреса памяти строки при проверке
  //Подскажите ошибку плз - заодно может, чтото оптимизировать можно тут ?


Последний раз редактировалось: Crazy (Ср Мар 08, 2006 1:56 am), всего редактировалось 2 раз(а)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 1:01 am    Заголовок сообщения: Ответить с цитатой

Перво на перво советую посмотреть исходники TIniFile (inifiles.pas)
Там имеется необходимый тебе парсинг Idea

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 1:08 am    Заголовок сообщения: Ответить с цитатой

-=Tujh=-, я же написал, что для самообразования этим занимаюсь Smile хочется перевести теорию из учебника по асму - в практику
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
TSergey
Генерал Майор


Репутация: 77    

Зарегистрирован: 25.03.2003
Сообщения: 6237


СообщениеДобавлено: Ср Мар 08, 2006 1:18 am    Заголовок сообщения: Ответить с цитатой

//Увеличиваем размер выделенной массиву памяти на 4 байта (размер указателя)
//Насколько я понимаю, при HeapReAlloc адрес выделяемой памяти не меняется, а лишь увеличивается ее размер
//Если невозможно выделить участок памяти такого размера - функция HeapReAlloc возвращает ошибку


Что-то мне говорит, что адрес меняется.
А ошибка возникнет, если не найдется ни одного нефрагментированного блока нужного размера.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 1:19 am    Заголовок сообщения: Ответить с цитатой

Crazy, ИМХО, если уж пишешь на Делфи/Си, то асемблеровских вставок должно быть как можно меньше, ибо теряется суть языка высокого уровня, автоматическая проверка типов и т.д.
В TIniFile нет asm-вставок...
Все реализовано целиком средствами Делфийского паскаля.

Но если тебе хочется именно на асме - то постарайся избежать использования WinAPI в распределении памяти. Проблем особых не должно быть, но могут. Делфи по умолчанию встраивает собственный менеджер памяти (getmem.inc если не ошибаюсь) и оперировать памятью лучше им.

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
TSergey
Генерал Майор


Репутация: 77    

Зарегистрирован: 25.03.2003
Сообщения: 6237


СообщениеДобавлено: Ср Мар 08, 2006 1:27 am    Заголовок сообщения: Ответить с цитатой

попробуй посмотреть в отладчике чему равны Integer(StringsArray)+i*4 в строке MessageBox(0,Pointer(Integer(StringsArray)+i*4),'',0);
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 1:43 am    Заголовок сообщения: Ответить с цитатой

TSergey, эммм, я это... того, отладчиком пользоваться не умею Embarassed Rolling Eyes
до этого все программы отлаживал "аналитически" - запускал, программа падала, я мысленно пытался понять почему она падает, неполучалось, поочередно коментировал все подозрительные фрагменты кода и находил ошибку
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 1:49 am    Заголовок сообщения: Ответить с цитатой

Crazy, это весь код ???
А то у меня программа "падает" с AV к памяти с адресом 0х000000 при попытке прочитать блок памяти при условии, что образ файла закончился...

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 1:57 am    Заголовок сообщения: Ответить с цитатой

-=Tujh=-, чуть поправил код (в первом посте), немного изменил финальную проверку + добавил проверку в тексте
и там и там винды ошибки Neutral
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 2:07 am    Заголовок сообщения: Ответить с цитатой

Crazy, сразу предупреждаю, с асемблером на Делфи не знаком =)

Замечено:
Если удалять #13#10 - у тебя в MessageBox идет мусор, если не удалять - первый все выводит правильно, второй - со сдвигом в два символа.

Сдается мне, что
//Увеличиваем размер выделенной массиву памяти на 4 байта (размер указателя)
//Насколько я понимаю, при HeapReAlloc адрес выделяемой памяти не меняется, а лишь увеличивается ее размер
у тебя там выделяется память под указатель, а записываются в неё данные...но это предположение...

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 2:29 am    Заголовок сообщения: Ответить с цитатой

Или меня на сон грядущий глючит...
Вобщем вот чего не понял:
Код:
  //Получаем размер файла
  dwFileSizeLow := GetFileSize(hFile,nil);
  //Хэндл кучи
  hHeap := GetProcessHeap();
  //Динамически выделям память под файл
  pBuffer := HeapAlloc(hHeap,0,dwFileSizeLow);
...
    call HeapReAlloc //Увеличиваем размер выделенной массиву памяти на 4 байта (размер указателя)
    //Насколько я понимаю, при HeapReAlloc адрес выделяемой памяти не меняется, а лишь увеличивается ее размер
    //Если невозможно выделить участок памяти такого размера - функция HeapReAlloc возвращает ошибку

У меня, например, получается, что файл размером 24 байта Arrow pBuffer указывает на область в 24 байта, но при этом, если я правильно понял код, я в эту область, кроме 24 байт данных пытаюсь еще запихнуть и 4 байтные указатели ???
Confused

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 2:29 am    Заголовок сообщения: Ответить с цитатой

Насчет адресации - набросал простенький примерчик
Код:

var
  y: array[0..2] of dword;
begin
  asm
    lea eax,y
    mov [eax+0],31337
    mov [eax+4],31338
    mov [eax+8],31339
  end;
  for i := 0 to 2 do
    MessageBox(0,PChar(IntToStr(Integer(Pointer(Integer(@y[0])+(i*4))^))),'',0); 
end;

Работает, но, тут используется delphi-массив (var: array of type)
а я хочу сам выделить память под массив указателей и в него же писать


Последний раз редактировалось: Crazy (Ср Мар 08, 2006 2:36 am), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 2:33 am    Заголовок сообщения: Ответить с цитатой

-=Tujh=- писал(а):

У меня, например, получается, что файл размером 24 байта Arrow pBuffer указывает на область в 24 байта, но при этом, если я правильно понял код, я в эту область, кроме 24 байт данных пытаюсь еще запихнуть и 4 байтные указатели ???
Confused

Есть массив указателей на строки StringsArray, его размер при каждой новой найденной строке увеличивается на размер указателя, затем вычисляется адрес-смещение в этом массиве и туда пишется адрес выделенной памяти под эту строку
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 2:43 am    Заголовок сообщения: Ответить с цитатой

Хм, пример 2, уже более походящий на мои извращенные задачи
Код:

var
  hHeap: THandle;
  x: Pointer;
begin
  hHeap := GetProcessHeap();
  x := HeapAlloc(hHeap,0,16);
  asm
    mov eax,x
    mov [eax+0],31337
    mov [eax+4],31338
    mov [eax+8],31339
    mov [eax+12],31340   
  end;
  for i := 0 to 3 do
    MessageBox(0,PChar(IntToStr(Integer(Pointer(Integer(x)+(i*4))^))),'',0);
  HeapFree(hHeap,0,x);
end;

Работает.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 2:46 am    Заголовок сообщения: Ответить с цитатой

Crazy, угу...понял...
Кстати вот, что нашел, чтобы HeapReAlloc не перемещяло память - необходимо сперва выполнить HeapLock а потом HeapUnlock.

Хотя это уже похоже на полночный бред Rolling Eyes

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Crazy
Подполковник


Репутация: 14    

Зарегистрирован: 11.08.2003
Сообщения: 1544
Откуда: ВИЗ

СообщениеДобавлено: Ср Мар 08, 2006 3:08 am    Заголовок сообщения: Ответить с цитатой

-=Tujh=-, почитал мсдн...
флаги HeapReAlloc'а

HEAP_REALLOC_IN_PLACE_ONLY
0x00000010 There can be no movement when reallocating a memory block. If this value is not specified, the function may move the block to a new location. If this value is specified and the block cannot be resized without moving, the function fails, leaving the original memory block unchanged.

Насколько я понимаю, если размер требуемой памяти больше чем свободный блок, то функция возвращает ошибку
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 3:14 am    Заголовок сообщения: Ответить с цитатой

Код:
  //Сам парсинг файла решил сделать на ассемблере (также для самообразования)
  asm
  //Для того чтобы распарсить файл на строки нужно найти все байты с значением 10 (#13#10 - окончание строки в текстовых windows файлах)

    @next:
   
    mov edi,pBuffer //Адрес строки исчтоника (цепочки байтов)
    mov eax, 10     //Ищем байт со значением 10
    mov ecx, NumberOfBytesRead //Количество байт в цепочке
    cld             //Ищем с начала строки
    repne scasb     //Сканируем цепочку байтов
    //В регистре edi у нас адрес байта в цепочке, который равен 10

    sub edi, pBuffer //Вычитаем адрес этого байта из адреса начала цепочки, чтобы узнать количество символов в строке
    sub NumberOfBytesRead, edi //Уменьшаем длину цепочки
    sub edi, 2 //Вычитаем из регистра edi еще 2 байта (#13#10)
    mov dwFind, edi //Копируем длину строки (без байт окончания строки во временную переменную)

    inc dwStringsArraySize //Увеличиваем на 1 размер массива строк

    push hHeap
    call HeapLock

    push SizeOf(Pointer)
    push StringsArray
    push 0
    push hHeap
    call HeapReAlloc //Увеличиваем размер выделенной массиву памяти на 4 байта (размер указателя)
    //Насколько я понимаю, при HeapReAlloc адрес выделяемой памяти не меняется, а лишь увеличивается ее размер
    //Если невозможно выделить участок памяти такого размера - функция HeapReAlloc возвращает ошибку

    push hHeap
    call HeapUnlock

    mov eax, dwFind //Переносим в регистр eax длину строки
    inc eax //Увеличиваем ее на 1, т.к. добавится символ окончания строки #0
   
    push eax
    push 0
    push hHeap
    call HeapAlloc  //Выделяем память под эту строку
    mov pTemp, eax  //Переносим адрес выделенного под строку участка памяти во временную переменную

    //Копируем из цепочки строку
    mov esi, pBuffer //адрес начала строки в цепочке
    mov edi, pTemp //адрес выделенного участка памяти
    mov ecx, dwFind //Количество копируемых символов
    cld  //Копируем с начала строки
    rep movsb //Копируем побайтово

    mov eax, pTemp //Переносим в регистр eax адрес последнеднего скопированного символа
    mov ebx, dwFind
    add eax, ebx

    mov [eax], 0  //Записываем байт со значем 0 - символ окончания строки

    //вызываем мессейжд для проверки "толи скопировалось в буфер"
    push 0
    push 0
    push pTemp
    push 0
    call MessageBox

Вроде работает как надо, в мессаджах по крайней мере именно те слова, что нужны.
Но выплыл один интересный момент, если в конце файла нет переноса строки - последнее слово будет обрезано на два символа.
Потому, что #13#10 в данном случает отсутствует Rolling Eyes

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
-=Tujh=-
Генерал Майор


Репутация: 8    

Зарегистрирован: 22.05.2005
Сообщения: 6414


СообщениеДобавлено: Ср Мар 08, 2006 3:36 am    Заголовок сообщения: Ответить с цитатой

И ошибку нашел, на строке HeapFree(hHeap,0,pBuffer); программа падала с AV по простой причине
//add pBuffer,2 //Увеличиваем адрес цепочки на размер скопированной строки + символы окончания строки #13#10

то есть pBuffer не соответствовал реальному адресу

Код:
  pBuffer := HeapAlloc(hHeap, 0, dwFileSizeLow);
  p := pBuffer;
...
  HeapFree(hHeap, 0, p);

исправило ситуацию Idea

Ну и вызов HeapFree до цикла
for i := 0 to dwStringsArraySize - 1 do
тоже ошибка - выводить нечего Wink

_________________
My soul in embraces of a crow.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Mega][ertZ
Мл.Сержант


Репутация: 0    

Зарегистрирован: 05.07.2005
Сообщения: 68
Откуда: Olympus NSP

СообщениеДобавлено: Пт Мар 10, 2006 10:45 pm    Заголовок сообщения: Ответить с цитатой

не могу ченить конкретное подсказать, вникать долго, могу лишь посоветовать подружиться с отладчиками, вроде Olly, да и встроенный в делфю может кое-чем помочь. помню, когда на асме писал, отладчик был незаменимой вещью. часто еще, если че не получалось, писал код на делфи, и смотрел дизасм листинг, чтоб понять, что делаю не правильно
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
ant_man
Майор


Репутация: 28    

Зарегистрирован: 08.03.2003
Сообщения: 1187
Откуда: с ВИЗа

СообщениеДобавлено: Сб Мар 11, 2006 3:09 am    Заголовок сообщения: Ответить с цитатой

Код:

   HANDLE hHeap=HeapCreate(0,0,0);
   char **poi=(char**)HeapAlloc(hHeap,0,0), *txt="abc\r\ndef\r\nhohoho\r\n"; int ptr1=(int)txt,len=strlen(txt),len2=0,d=0,e=0;
   __asm {

cld
metk:
mov edi,ptr1
mov eax,10
mov ecx,len
repne scasb
mov eax,len
sub eax,ecx
push eax
mov len,ecx

inc len2
mov eax,len2
shl eax,2
push eax
push poi
push 0
push hHeap
call dword ptr [HeapReAlloc]
mov poi,eax

mov eax,[esp]
dec eax
push eax
push 0
push hHeap
call dword ptr [HeapAlloc]
mov ecx,len2
mov edx,poi
mov [edx+ecx*4-4],eax ; чудеса адресации :)

mov edi,eax
mov esi,ptr1
pop ecx
sub ecx,2
repz movsb
mov [byte ptr edi],0
inc esi
inc esi
mov ptr1,esi

mov eax,len
and eax,eax
jnz metk
}
for(int i=0; i<len2; i++)MessageBoxA(NULL,poi[i],"?",MB_OK);


HeapReAlloc может поменять указатель.
edi после rep стоит на следущем байте за найденным

_________________
Надо же... живу...
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
assch
Дух


Репутация: 0    

Зарегистрирован: 05.02.2011
Сообщения: 3


СообщениеДобавлено: Пн Фев 28, 2011 4:11 am    Заголовок сообщения: Ответить с цитатой

Код:
.data
fName    db '0.txt',0
fbox     db ' ',0
hHeap    dd 0
temp     dd 0

.code
start:
invoke CreateFile,addr fName,80000000h,1,0,3,80h,0
mov ebp,eax
invoke GetFileSize,ebp,0
mov esi,eax
invoke GetProcessHeap
mov hHeap,eax
invoke HeapAlloc,hHeap,0,esi
mov edi,eax
invoke ReadFile,ebp,edi,esi,addr temp,0
invoke CloseHandle,ebp
xor edx,edx
xor ebx,ebx
mov eax,edi
Metka1:
mov cl,[eax]
inc edx
inc ebx
inc eax
cmp cl,0ah
jne Metka2
mov  byte ptr [eax-1],0
sub eax,ebx
pusha
invoke MessageBox,0,eax,addr fbox,20h
popa
cmp edx,esi
jg Metka3
add eax,ebx
xor ebx,ebx
jmp Metka1
Metka2:
cmp edx,esi
jl Metka1
Metka3:
invoke  HeapFree,hHeap,0,edi
invoke  ExitProcess,0
end start
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему       Список форумов Forum.profintel.ru -> Программерский раздел Часовой пояс: GMT + 6
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы не можете скачивать файлы