leo Мамой клянус, стоит разкоментить push/pop и все, AV получаем, а без него не могу обнулить... Я то и так и так уже, и через регистр его и в стек. Но оно тупо бац и все тут. Code (Text): asm lea edi, Context mov esi, offset(tmp) movsd movsd movsd movsd // push eax //Раскоментить 2 строки и AV получили :( // pop eax //Но они ну ничего не делают то даже // xor eax, eax mov ecx, 18 rep stosd end; А могет компилятор увидеть что я EAX юзаю и чтонить сотворить с ним заранее и поздже ? По крайней мере в листинге я не заметил ничего такого...
Shooshpanchik Что такое "AV" ? Сохраняйте все регистры(pushad) в том числе флажки(pushfd), если не известно какие должна сохранять процедуры, можно юзать pushad. Работа кода изза пустой пары инструкций(push eax/pop eax) может быть нарушена по двум причинам. Это размер кода меняется, либо затирается значение в стек, хотя он начиная с вершины вниз должен быть доступен, вероятно первое. В любом случае следует под отладчиком посмотреть.
Shooshpanchik Упертый ты ... Говорю тебе, что вставки не надежны, т.к. компилер может сохранить регистры перед вставкой, а может и не сохранить. Засунь свою инициализацию в асм-функцию и будет все пучком: Code (Text): procedure InitMd5Context(const State:TMd5State;var Context:TMd5Context);register; const ZeroCount = (SizeOf(TMd5Context)-SizeOf(TMd5State)) div 4; asm push esi //сохраняем esi и edi, т.к. компилер в асм-функции точно ничего не сохраняет push edi mov esi,eax //@State mov edi,edx //@Context movsd movsd movsd movsd xor eax,eax //спокойно обнуляем eax, т.к. он больше не нужен mov ecx, ZeroCount rep stosd pop edi //восстанавливаем сохраненные edi и esi (в обратном порядке !) pop esi end;
AccesViolation Code (Text): pushfd popfd норма Code (Text): push ecx pop ecx норма Code (Text): pushad popad И снова AV Причем даже если просто тупо написать пару подряд. --------------------------- Debugger Exception Notification --------------------------- Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 004AFF3C in module 'Project1.exe'. Read of address 004DE000'. --------------------------- Break Continue Help --------------------------- Ну это мало кому помогет. И этот AV происходит далеко не в том месте где код меняю. И при трассировке далеко не сразу. Т.е. работа проги не сразу нарушается... Не, ну нафик, так рассуждать вслепую, в 23-с_копейками залью весь сырец на какой-нить файлообменник. У меня уже башка болит от этого...
leo Мож и упертый, но само поведение проги уже заинтересовало. Мож я чего-то еще незнаю, зато познаю. Мне то ее никто не запрещает изначально обнулить ZeroMemory каким нить... (или FillChar)
Shooshpanchik :wall: Надо не тупо писать, а с головой - pushad в начале вставки и popad в конце, а не в любом месте, когда уже esi,edi и eax безнадежно затерты
leo Он даже сейчас скорее всего не поймет. Shooshpanchik Надо делать так: Code (Text): ... push eax xor eax, eax mov ecx, 18 rep stosd pop eax
Clerk Выложил бы, но там больше 800 килов тогда, я пока что не осилю, часа через 1.5 будет у меня анлим...
Ну точно, дельфовый глюк при сохранении регистров. Вот так дельфи 7 пытается сохранить регистры перед асм-вставкой: Code (Text): push ebx push esi push edi mov ebx,ecx //в есх указатель @Result mov esi,eax //!!! eax якобы "сохраняется" в esi //--- начало вставки --- lea edi,[ebp-XXX] lea esi,YYY //!!! - тут esi, в котором находится eax = @Buffer, затирается ... //--- конец вставки --- lea eax,[ebp-XXX] mov ecx,esi //!!! - тут в ecx вместо @Buffer оказывается указатель на конец tmp xchg edx,ecx call MD5Update2 //!!! в функцию передается неверный @Buffer
Вот ведь как оказалось, а не додумался в конце посмотреть что происходит. Т.е. реально только переписать все на чистый асм и функцию сделать assebmler ? ЗЫ, А какой OBJ нужен дельфе ? (COFF или OBJ)
Насчет глюкавости я погорячился, просто в отношении асм-вставок действуют те же правила, что и для функций. Т.е. в асм-вставке можно свободно изменять eax, edx и ecx - тут компилер сам увидит модификацию этих регистров и в сл.необходимости позаботится об их сохранении и восстановлении. А вот изменение ebx, esi и edi (ну и ес-но ebp) компилером не проверяется, и вся забота об их сохранении\восстановлении как в асм-вставках, так и в асм-функциях, целиком ложится на (ш)кодера Поэтому в твоем суперкоде не хватает push esi+push edi в начале вставки и соотв-щих pop в конце. Хотя по любому - вставка, это фигня, которая сбивает с толку оптимизатор и приводит к лишним сохранениям\восстановлениям регистров и параметров. Вот ты заюзал вставку на самом входе функции и вправе считать, что @Buffer сидит в EAX. Вопрос на засыпку - а если сначала вызвать одну или несколько функций, и только потом использовать вставку, то где будет сидеть @Buffer ? Наверняка в одном из регистров, но в каком ты не знаешь, и если по наивности заюзаешь EAX, то скорее всего получишь AV или другой глюк. Поэтому придется вместо регистра явно указывать Buffer, а это приведет к тому, что компилер вынужден будет в начале функции запихнуть EAX=@Bufer в локальную переменную и в твоей вставке (а может и в дальнейшем) вместо регистра обращаться к этой переменной. Вместо оптимизации получаем антиоптимизацию.