Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка при вызове ReallocMem в ассемблере [D7, WinXP]


Страницы:   1 2 3 4

Mx ©   (2005-07-15 09:50:00) 

Написал две подпрограммы для работы с битами, обе ассемблерные. Первая возвращает значение бита по индексу, вторая - устанавливает, а если надо, и расширяет диапазон. Последнее производится засчет ReallocMem, но че то не фурычит. Не могу понять. Интересно, что я протестил код некой _ReallocMem из System.pas (а не из GetMem.inc), так там тоже при вызове MemoryManager.ReallocMem происходит ошибка. А может я указываю адрес не той процедуры?

Исходный текст:

function GetBit(Buffer: Pointer; Index: Integer): Boolean;
asm
     MOV   ECX,EDX
     SAR   ECX,3
     ADD   EAX,ECX
     SUB   EDX,ECX
     BT    [EAX],EDX
     SETC  Result      
end;

procedure SetBit(var Buffer: Pointer; Index: Integer; Value: Boolean);
asm
     PUSH  ECX
     PUSH  EDX
     SAR   EDX,3
     INC   EDX
     CALL  System.@ReallocMem
     MOV   ECX,EDX
     POP   EDX
     ADD   EAX,ECX
     SUB   EDX,ECX
     POP   ECX
     CMP   CL,0
     JE    @@clr
@@set:
     BTS   [EAX],EDX
     RET
@@clr:
     BTC   [EAX],EDX}
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 P: Pointer;
begin
 P := nil;
 try
   SetBit(P, 1, True);
   SetBit(P, 2, True); // ошибка возникает тут, при повторном вызове
   SetBit(P, 8, True);
   SetBit(P, 13, True);
   SetBit(P, 12, True);
 finally
   FreeMem(P);
 end;
end;


Ошибка: "всеми любимый" EAccessViolation

Спасибо.


DiamondShark   (2005-07-15 11:39:00) [61]


> Каким образом? Что надо исправить?

Сохранять EAX перед вызовом @ReallocMem

Да и дальше фигня полная. EAX содержит не адрес буфера, а адрес адреса буфера.
А ты один уровень косвенности потерял.


Anatoly Podgoretsky   (2005-07-15 11:37:00) [62]

Mx ©   (15.07.05 11:27) [9]
Сохранять, остальные ты почему то сохраняешь.


Digitman   (2005-07-15 11:34:00) [63]

ADD   EAX,ECX <- а здесь ты складываешь неизвестно что с новым адресом нового буфера


Mx   (2005-07-15 11:27:00) [64]


> Anatoly Podgoretsky ©   (15.07.05 11:25) [7]
> Испорчен var Buffer [EAX]

Каким образом? Что надо исправить?


Mx   (2005-07-15 11:26:00) [65]


> REA   (15.07.05 10:50) [4]
> А TBits не покатит?

Придется хранить сотни экземпляров TBits, а требуется и память экономить (поэтому биты, а не массив Boolean) и время.


> Digitman ©   (15.07.05 11:10) [5]
> SUB   EDX,ECX <- проблема здесь : из номера бита вычитаешь
> вирт.адрес

Оба! Я оставил MOV ECX,EDX после ReallocMem так, как при первом вызове EDX нуль, а потом то нет! Но я не заметил. Пока сваливать надо, вечером отпишусь, что получилось.


Anatoly Podgoretsky   (2005-07-15 11:25:00) [66]

Испорчен var Buffer [EAX]


Sha   (2005-07-15 11:12:00) [67]

Вызываемая функция имеет право изменять содержимое eax, edx, ecx.


Digitman   (2005-07-15 11:10:00) [68]

..
    CALL  System.@ReallocMem
    MOV   ECX,EDX
    POP   EDX
    ADD   EAX,ECX
    SUB   EDX,ECX<- проблема здесь : из номера бита вычитаешь вирт.адрес
    POP   ECX


REA   (2005-07-15 10:50:00) [69]

А TBits не покатит?


Mx   (2005-07-15 10:45:00) [70]


> Digitman ©
> пошаговую трассировку с контролем состояния РОН до и после
> вызова System.@ReallocMem делал ?

Делал. Перед вызовом в EAX адрес Buffer'а. После ReallocMem в EAX уже лежит значение этой переменной. К тому же обнуляется EDX, ввиду чего его приходится POP'ить. Но это мне, к сожалению, ни о чем не говорит.


> Amoeba ©

Такие процедуры всего лишь проверяют бит в пределах одного байта. У меня же бит может иметь индекс свыше 31, плюс автоматически выделяется память. Мне это надо делать в нескольких местах и заниматься выделением памяти и определением индекса байта каждый раз мне не хочется.


Amoeba   (2005-07-15 10:20:00) [71]

Не изобретай велосипед! Посмотри как это сделано в бибилотеке QSrtings^

function Q_BitTest(P: Pointer; Index: Integer): Boolean;
asm
       BT      [EAX],EDX
       SETC    AL
end;

function Q_BitSet(P: Pointer; Index: Integer): Boolean;
asm
       BTS     [EAX],EDX
       SETC    AL
end;

function Q_BitReset(P: Pointer; Index: Integer): Boolean;
asm
       BTR     [EAX],EDX
       SETC    AL
end;

function Q_BitToggle(P: Pointer; Index: Integer): Boolean;
asm
       BTC     [EAX],EDX
       SETC    AL
end;


Digitman   (2005-07-15 10:06:00) [72]

пошаговую трассировку с контролем состояния РОН до и после вызова System.@ReallocMem делал ?


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо