Ассемблер и Delphi

Тема в разделе "WASM.BEGINNERS", создана пользователем Shooshpanchik, 14 сен 2009.

  1. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    leo
    Мамой клянус, стоит разкоментить push/pop и все, AV получаем, а без него не могу обнулить... Я то и так и так уже, и через регистр его и в стек. Но оно тупо бац и все тут.

    Код (Text):
    1.   asm
    2.     lea edi, Context
    3.     mov esi, offset(tmp)
    4.     movsd
    5.     movsd
    6.     movsd
    7.     movsd
    8. //    push eax //Раскоментить 2 строки и AV получили :(
    9. //    pop eax //Но они ну ничего не делают то даже
    10. //    xor eax, eax
    11.     mov ecx, 18
    12.     rep stosd
    13.   end;
    А могет компилятор увидеть что я EAX юзаю и чтонить сотворить с ним заранее и поздже ? По крайней мере в листинге я не заметил ничего такого...
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Shooshpanchik
    Что такое "AV" ?
    Сохраняйте все регистры(pushad) в том числе флажки(pushfd), если не известно какие должна сохранять процедуры, можно юзать pushad.
    Работа кода изза пустой пары инструкций(push eax/pop eax) может быть нарушена по двум причинам. Это размер кода меняется, либо затирается значение в стек, хотя он начиная с вершины вниз должен быть доступен, вероятно первое.
    В любом случае следует под отладчиком посмотреть.
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Shooshpanchik
    Упертый ты ...
    Говорю тебе, что вставки не надежны, т.к. компилер может сохранить регистры перед вставкой, а может и не сохранить. Засунь свою инициализацию в асм-функцию и будет все пучком:
    Код (Text):
    1. procedure InitMd5Context(const State:TMd5State;var Context:TMd5Context);register;
    2. const
    3.   ZeroCount = (SizeOf(TMd5Context)-SizeOf(TMd5State)) div 4;
    4. asm
    5.   push esi  //сохраняем esi и edi, т.к. компилер в асм-функции точно ничего не сохраняет
    6.   push edi
    7.   mov esi,eax  //@State
    8.   mov edi,edx  //@Context
    9.   movsd
    10.   movsd
    11.   movsd
    12.   movsd
    13.  
    14.   xor eax,eax //спокойно обнуляем eax, т.к. он больше не нужен
    15.   mov ecx, ZeroCount
    16.   rep stosd
    17.   pop edi  //восстанавливаем сохраненные edi и esi (в обратном порядке !)
    18.   pop esi
    19. end;
     
  4. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    AccesViolation

    Код (Text):
    1.     pushfd
    2.     popfd
    норма
    Код (Text):
    1.     push ecx
    2.     pop ecx
    норма

    Код (Text):
    1.    pushad
    2.    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-с_копейками залью весь сырец на какой-нить файлообменник. У меня уже башка болит от этого...
     
  5. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Ой, вот я тупанул, вырезал историю и сам бинарник, сжал и получил 37 килов. Это и по GPRS нежалко
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Shooshpanchik
    Выложите экзе, сурцы не нужны.
     
  7. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    leo
    Мож и упертый, но само поведение проги уже заинтересовало. Мож я чего-то еще незнаю, зато познаю.
    Мне то ее никто не запрещает изначально обнулить ZeroMemory каким нить... (или FillChar)
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Shooshpanchik
    :wall:
    Надо не тупо писать, а с головой - pushad в начале вставки и popad в конце, а не в любом месте, когда уже esi,edi и eax безнадежно затерты
     
  9. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    leo
    Он даже сейчас скорее всего не поймет.
    Shooshpanchik
    Надо делать так:
    Код (Text):
    1.     ...
    2.     push eax
    3.     xor eax, eax
    4.     mov ecx, 18
    5.     rep stosd
    6.     pop eax
     
  10. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Clerk
    Выложил бы, но там больше 800 килов тогда, я пока что не осилю, часа через 1.5 будет у меня анлим...
     
  11. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    2All
    да я ж тестю пока, потому и пишу пару подряд.
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ну точно, дельфовый глюк при сохранении регистров. Вот так дельфи 7 пытается сохранить регистры перед асм-вставкой:
    Код (Text):
    1.   push ebx
    2.   push esi
    3.   push edi
    4.   mov ebx,ecx  //в есх указатель @Result
    5.   mov esi,eax   //!!! eax якобы "сохраняется" в esi
    6.   //--- начало вставки ---
    7.   lea edi,[ebp-XXX]
    8.   lea esi,YYY  //!!! - тут esi, в котором находится eax = @Buffer, затирается
    9.   ...
    10.   //--- конец вставки ---
    11.   lea eax,[ebp-XXX]
    12.   mov ecx,esi  //!!! - тут в ecx вместо @Buffer оказывается указатель на конец tmp
    13.   xchg edx,ecx
    14.   call MD5Update2 //!!! в функцию передается неверный @Buffer
     
  13. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    Вот ведь как оказалось, а не додумался в конце посмотреть что происходит.
    Т.е. реально только переписать все на чистый асм и функцию сделать assebmler ?

    ЗЫ, А какой OBJ нужен дельфе ? (COFF или OBJ)
     
  14. Shooshpanchik

    Shooshpanchik Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    117
    (COFF или OMF)

    модеры верните редактирование
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Насчет глюкавости я погорячился, просто в отношении асм-вставок действуют те же правила, что и для функций. Т.е. в асм-вставке можно свободно изменять eax, edx и ecx - тут компилер сам увидит модификацию этих регистров и в сл.необходимости позаботится об их сохранении и восстановлении. А вот изменение ebx, esi и edi (ну и ес-но ebp) компилером не проверяется, и вся забота об их сохранении\восстановлении как в асм-вставках, так и в асм-функциях, целиком ложится на (ш)кодера ;)
    Поэтому в твоем суперкоде не хватает push esi+push edi в начале вставки и соотв-щих pop в конце.

    Хотя по любому - вставка, это фигня, которая сбивает с толку оптимизатор и приводит к лишним сохранениям\восстановлениям регистров и параметров. Вот ты заюзал вставку на самом входе функции и вправе считать, что @Buffer сидит в EAX. Вопрос на засыпку - а если сначала вызвать одну или несколько функций, и только потом использовать вставку, то где будет сидеть @Buffer ? Наверняка в одном из регистров, но в каком ты не знаешь, и если по наивности заюзаешь EAX, то скорее всего получишь AV или другой глюк. Поэтому придется вместо регистра явно указывать Buffer, а это приведет к тому, что компилер вынужден будет в начале функции запихнуть EAX=@Bufer в локальную переменную и в твоей вставке (а может и в дальнейшем) вместо регистра обращаться к этой переменной. Вместо оптимизации получаем антиоптимизацию.