В коде @DrawXLineA (сообщение выше)
идёт вызов процедуры Call Draw
которая работает нормально когда она "сама-по-себе", (т.е не внутри какой либо процедуры)
скорее всего, она не очень корректна по "пуш" и "поп"
подскажите, как не ковыряя процедуры, до её начала сохранить указатель стека и всех регистров, а после её выполнения вернуть состояние регистров и стека, учитывая то, что "пушей" и "попов" может быть разное количество (надеюсь "пушей" там больше :-).
Вопрос
возможно PUSHA, POPA.
Похоже до меня дошло! :-)
....
@esp_: rd 1
.....
Pusha;
mov [@esp_], esp
Call Draw
mov esp,[@esp_]
popa
УРА ! ЗАРАБОТАЛО!
ИЛИ МОЖНА КАК-ТО ПОУМНЕЕ ?
....
@esp_: rd 1
.....
Pusha;
mov [@esp_], esp
Call Draw
mov esp,[@esp_]
popa
УРА ! ЗАРАБОТАЛО!
ИЛИ МОЖНА КАК-ТО ПОУМНЕЕ ?
Через add esp,..
попробуй
попробуй
много лишних команд, например
mov [@esp_], esp
mov esp,[@esp_]
mov [@esp_], esp
mov esp,[@esp_]
и еще, ты перед вызовом ф-ции пишешь pusha? А то я не понял почему закоментирован
А все понял)
[quote="pavelyakov"]Через add esp,..
попробуй[/quote]
ну add esp поменяет сам указатель!... а регистры то восстановить надо!.... до вызова процедуры Draw (из процедуры DrawXLineA1) вызывающая процедура ведь расчитывала на их?! Это же не "ручная лепка" :-) это скомпилированный код дельфи в который надо вставлять вызовы процедур, т.е.
DrawXLineA1; - представляет из себя, скомпилированный дельфи-асм-код, в который делается "врезка", для вызова другой процедуры Draw, ну и параметры должны передаваться для Draw, (о возврате параметров из Draw, вопрос пока не стоит, я всё таки еще пока новичёк :-) ) Вот поэтому, я хочу до выполнения процедуры Draw сохранить всё так как было и после выполнения Draw вернуть как ни в чём не бывало. :-)
ВОТ ПОКА ТАК!
Вот еще вопрос возник... Передача регистров видимо будет осуществляться через аналоги зарезервированных регистров, т.е.
.............
@ECX_ rd 1
.............
SetECX_:
Mov [@ECX_],EAX
ret
.................
call SetECX_ ;
.................
как SetECX_ сделать макросом т.е. SetECX_ в коде должно заменять Mov [@ECX_],EAX "один к одному"?
попробуй[/quote]
ну add esp поменяет сам указатель!... а регистры то восстановить надо!.... до вызова процедуры Draw (из процедуры DrawXLineA1) вызывающая процедура ведь расчитывала на их?! Это же не "ручная лепка" :-) это скомпилированный код дельфи в который надо вставлять вызовы процедур, т.е.
DrawXLineA1; - представляет из себя, скомпилированный дельфи-асм-код, в который делается "врезка", для вызова другой процедуры Draw, ну и параметры должны передаваться для Draw, (о возврате параметров из Draw, вопрос пока не стоит, я всё таки еще пока новичёк :-) ) Вот поэтому, я хочу до выполнения процедуры Draw сохранить всё так как было и после выполнения Draw вернуть как ни в чём не бывало. :-)
ВОТ ПОКА ТАК!
Вот еще вопрос возник... Передача регистров видимо будет осуществляться через аналоги зарезервированных регистров, т.е.
.............
@ECX_ rd 1
.............
SetECX_:
Mov [@ECX_],EAX
ret
.................
call SetECX_ ;
.................
как SetECX_ сделать макросом т.е. SetECX_ в коде должно заменять Mov [@ECX_],EAX "один к одному"?
ВО ЕЩЕ: В дедьфи в помощи (о Cardinal 0..4294967295 unsigned 32-bit )написано следующее:
An integer type represents a subset of the whole numbers. The generic integer types are Integer and Cardinal; use these whenever possible, since they result in the best performance for the underlying CPU and operating system. The table below gives their ranges and storage formats for the current 32-bit Delphi compiler.
Тупой перевод:
Тип целого представляет подмножество целых чисел. Типы общего целого - Целое и Кардинал; используйте их там, где возможно, поскольку они заканчиваются наилучшим показателем для основной CPU и операционной системы. Таблица ниже дает их области и память форматируется для текущего 32-битового компилятора Delphi.
Т.е. другими словами в асме можно (и даже так лучше) использовать ГДЕ ЭТО ВОЗМНОЖНО регистры "целиком" (eax), а не их "половинки" (AX) или "четвертинки (AH, AL ) ? Или всё таки арифметичекские действия с "половинками" и "четвертинками будут происходить быстрее ?
An integer type represents a subset of the whole numbers. The generic integer types are Integer and Cardinal; use these whenever possible, since they result in the best performance for the underlying CPU and operating system. The table below gives their ranges and storage formats for the current 32-bit Delphi compiler.
Тупой перевод:
Тип целого представляет подмножество целых чисел. Типы общего целого - Целое и Кардинал; используйте их там, где возможно, поскольку они заканчиваются наилучшим показателем для основной CPU и операционной системы. Таблица ниже дает их области и память форматируется для текущего 32-битового компилятора Delphi.
Т.е. другими словами в асме можно (и даже так лучше) использовать ГДЕ ЭТО ВОЗМНОЖНО регистры "целиком" (eax), а не их "половинки" (AX) или "четвертинки (AH, AL ) ? Или всё таки арифметичекские действия с "половинками" и "четвертинками будут происходить быстрее ?
ALEXS1983 писал(а):
> в асме можно (и даже так лучше) использовать ГДЕ ЭТО ВОЗМНОЖНО регистры "целиком"
> (eax), а не их "половинки" (AX) или "четвертинки (AH, AL ) ? Или всё таки арифметичекские
> действия с "половинками" и "четвертинками будут происходить быстрее ?
Лучше использовать целые регистры eax, по идее должно работать быстрее. Дробные регистры (AX, AH, AL, ...) вроде-бы остались среди команд ассемблера для совместимости со старыми программами.
> в асме можно (и даже так лучше) использовать ГДЕ ЭТО ВОЗМНОЖНО регистры "целиком"
> (eax), а не их "половинки" (AX) или "четвертинки (AH, AL ) ? Или всё таки арифметичекские
> действия с "половинками" и "четвертинками будут происходить быстрее ?
Лучше использовать целые регистры eax, по идее должно работать быстрее. Дробные регистры (AX, AH, AL, ...) вроде-бы остались среди команд ассемблера для совместимости со старыми программами.
ALEXS1983
Просто замечательная среда для изучения ассемблера. Оптимизирует так, чтоб ты ничего не понял.
Если подпрограмма принимает три параметра, то выглядит так:
push ebp
mov ebp, esp
параметры адресуются через [ebp+8+?], можно пользоваться стеком
mov esp, ebp
pop ebp
ret 12 ; три рор после возврата
Выделить место под две локальные переменные можно вручную:
sub esp, 8
...
тут адресуются через [esp+?]
push eax
тут адресуются через [esp+4+?]
pop eax
...
add esp, 8
ret
Если и то и то:
sub esp, 8
push ebp
mov ebp, esp
параметры адресуются через [ebp+16+?]
локальные переменные через [ebp+4+?]
mov esp, ebp
pop ebp
add esp, 8
ret 12
По конвенции stdcall подпрограмма обязана сохранять содержимое регистров bx, si, di, bp. Регисты ax, dx, cx могут не сохраняться или использоваться для возврата результата.
Просто замечательная среда для изучения ассемблера. Оптимизирует так, чтоб ты ничего не понял.
Если подпрограмма принимает три параметра, то выглядит так:
push ebp
mov ebp, esp
параметры адресуются через [ebp+8+?], можно пользоваться стеком
mov esp, ebp
pop ebp
ret 12 ; три рор после возврата
Выделить место под две локальные переменные можно вручную:
sub esp, 8
...
тут адресуются через [esp+?]
push eax
тут адресуются через [esp+4+?]
pop eax
...
add esp, 8
ret
Если и то и то:
sub esp, 8
push ebp
mov ebp, esp
параметры адресуются через [ebp+16+?]
локальные переменные через [ebp+4+?]
mov esp, ebp
pop ebp
add esp, 8
ret 12
По конвенции stdcall подпрограмма обязана сохранять содержимое регистров bx, si, di, bp. Регисты ax, dx, cx могут не сохраняться или использоваться для возврата результата.
[quote="Pathoswithin"]Просто замечательная среда для изучения ассемблера. Оптимизирует так, чтоб ты ничего не понял.[/quote]
Да нормально! :-) Разберёмся! :-) Спасибо за разъяснение!
[quote="Pathoswithin"]По конвенции stdcall подпрограмма обязана сохранять содержимое регистров bx, si, di, bp. Регисты ax, dx, cx могут не сохраняться или использоваться для возврата результата.[/quote]
О! А это интересно! Думаю пригодится в будущем! Спасибо!
Тут еще одна хрень "нарисовалась" см. следующее сообщение
Да нормально! :-) Разберёмся! :-) Спасибо за разъяснение!
[quote="Pathoswithin"]По конвенции stdcall подпрограмма обязана сохранять содержимое регистров bx, si, di, bp. Регисты ax, dx, cx могут не сохраняться или использоваться для возврата результата.[/quote]
О! А это интересно! Думаю пригодится в будущем! Спасибо!
Тут еще одна хрень "нарисовалась" см. следующее сообщение
Создавал пошаговый урок для своего форума. И тут натолкнулся на облом который я врядле самостоятельно решу. Прошу помощи у спецов.
В в архиве https://cloud.mail.ru/public/6yYg/579fb7Sx8 пошагово урок, папки Part00, Part01, Part02
Part03, который постепенно преобразовывает одну процедуру писанную на дельфи на асм....
Ближе к делу, см. KOS05\Part03\EL_indicator.dpr процедура DrawXLine верно работает написанная на дельфи, также верно работает эта же процедура на асме в асм-вставках дельфи DrawXLineA (процедура находится тоже в файле, KOS05\Part03\EL_indicator.dpr ) и вот после того как я “перебазировал” процедуру DrawXLineA в FASM, (файл KOS05\Part03\ Lesson.prt ) часть когда (!!ЧАСТЬ!! буквально несколько команд! ) работает не верно!
Прошу помощи.
В в архиве https://cloud.mail.ru/public/6yYg/579fb7Sx8 пошагово урок, папки Part00, Part01, Part02
Part03, который постепенно преобразовывает одну процедуру писанную на дельфи на асм....
Ближе к делу, см. KOS05\Part03\EL_indicator.dpr процедура DrawXLine верно работает написанная на дельфи, также верно работает эта же процедура на асме в асм-вставках дельфи DrawXLineA (процедура находится тоже в файле, KOS05\Part03\EL_indicator.dpr ) и вот после того как я “перебазировал” процедуру DrawXLineA в FASM, (файл KOS05\Part03\ Lesson.prt ) часть когда (!!ЧАСТЬ!! буквально несколько команд! ) работает не верно!
Прошу помощи.
Тогда скажи сразу, какие команды не работают.
ну если бы я сам знал, то не спрашивал бы :-)
в общем почему-то не работает ветка
.............
case drawType of
0:begin posy:=posy-1;x1:=x1-1;posx:=posx+1; end;
.....................
на асме она
..........................
;//EL_indicator.dpr.25: 0:begin posy:=posy-1;x1:=x1-1;posx:=posx+1; end;
@STR25: dec esi
dec dword [ebp-$08]
inc dword [ebp-$04]
jmp @STR31;// jmp +$0d
........................
Но самое интересное, что в других ветках "case drawType of" ведь тоже "posy:=posy-1;", "x1:=x1-1;", "posx:=posx+1;" там они нормально работают. Да и в дельфи в асм вставках работаю нормально.
Можно бы было сказать что мои "врезки" в процедуру некоректные, но они в конце процедуры. Да и процедура вызывается 4 раза (по всем веткам case drawType of ) ведь нормально работают.
Вот подумал.... я то проверял в KlbrInWin, а не в самой системе. А в KlbrInWin могут быть глюки или ошибки ?
в общем почему-то не работает ветка
.............
case drawType of
0:begin posy:=posy-1;x1:=x1-1;posx:=posx+1; end;
.....................
на асме она
..........................
;//EL_indicator.dpr.25: 0:begin posy:=posy-1;x1:=x1-1;posx:=posx+1; end;
@STR25: dec esi
dec dword [ebp-$08]
inc dword [ebp-$04]
jmp @STR31;// jmp +$0d
........................
Но самое интересное, что в других ветках "case drawType of" ведь тоже "posy:=posy-1;", "x1:=x1-1;", "posx:=posx+1;" там они нормально работают. Да и в дельфи в асм вставках работаю нормально.
Можно бы было сказать что мои "врезки" в процедуру некоректные, но они в конце процедуры. Да и процедура вызывается 4 раза (по всем веткам case drawType of ) ведь нормально работают.
Вот подумал.... я то проверял в KlbrInWin, а не в самой системе. А в KlbrInWin могут быть глюки или ошибки ?
Who is online
Users browsing this forum: No registered users and 3 guests