1 | ||||||
__asm вставки (процессор Pentium)18.03.2013, 00:45. Показов 1099. Ответов 9
Метки нет (Все метки)
Пишу в вижуал Студии, делаю ассемблерные вставки, хочу вызывать си-процедуру, в которой тоже ассемблер - просто поменять значение одного регистра, не хочу никаких стеков, ОЗУ и прочего. При выходе похоже не восстанавливается из стека адрес возврата и программа вылетает. Подскажите, где ошибка? (Лишние куски кода убрал для краткости)
0
|
18.03.2013, 00:45 | |
Ответы с готовыми решениями:
9
Профилирование, C++ и вставки ASM, прошу совета Builder C++ и asm вставки Вставки на asm Asm-вставки не работают |
Maniac
|
||||||
18.03.2013, 00:58 | 2 | |||||
Здесь ты его и сломал... не забывай про пролог/эпилог функции в зависимости от конвенции вызова.
1
|
18.03.2013, 01:08 [ТС] | 3 |
Спасибо, насколько я понял, при вызове CALL компилятор автоматически засовывает в стек что-то-там в неизвестном количестве, поэтому RET надо передать параметр - на сколько прыгнуть вглубь стека при возврате? Просто я прочитал, что если в процедуре не использовать определенные регистры, то компилятор и не будет их сохранять, я и старался использовать те,которые не в списке. Или я чего-то недопонимаю...
ЗЫ в чистом asm было проще - никто за тебя ничего не пушил и не попил и не портил адреса возвратов...
0
|
18.03.2013, 03:09 [ТС] | 5 | ||||||||||
Скопипастил этот кусок кода в свою функцию - на этапе компиляции выдает кучу ошибок. Придется с этим разбираться... Собственно, основная функция работает, если не вызывать вложенную функцию а писать её содержимое несколько раз в коде. Хотел сделать красиво - вынести наружу, но навскидку не получилось, ни функцией ни макросом. Сама эта подфункция проста до безобразия, никаких входных-выходных параметров, использует и изменяет только один регистр, никаких окружающих контекстов не надо сохранять. Неужели нет красивого решения этого вопроса - написать не макросом а функцией несколько простейших операций с регистром без сохранения контекста в стек?
Все равно спасибо за науку, буду ковыряться дальше. Добавлено через 40 минут Нашел листинг - увидел много нового и интересного Не думал, что мои простые операции компилятор будет окружать таким.... вниманием
Спасибо людям - подсказали про директиву naked - а то бы долго думал почему в мире все так несправедливо
0
|
18.03.2013, 04:00 | 6 |
Не по теме: везет вам, вижуал-студиевцам:) в gcc такой опции нет, и, видимо, не будет под x86. а жаль по теме, все правильно, компилируйте си код в исходник на ассемблере (не знаю, каким ключом это делать в студии, извините), и увидите, какой там пролог, эпилог, заодно call convensions выучите. можно еще посмотреть, что получается при указании ключей оптимизации. интересно! правда по-простому, можно применять pusha/popa . с другой стороны, вы и только вы знаете, какие регистры использутся внутри вашего ассемблерного кода (компилятор тупо копипастит ваши куски), поэтому можете сохранять только те регистры, которые реально используются.
1
|
18.03.2013, 10:40 | 7 |
инструкция CALL кладет в стек адрес возврата, т.е. адрес инструкции, следующей за call.
RET ничего передавать не надо, она просто выталкивает из стека 4(8) байт, думает что это адрес и передает управление по этому адресу. Поэтому задача программиста позаботиться о том, чтобы RET взяла из стека валидный адрес.
1
|
18.03.2013, 13:56 [ТС] | 8 |
NEbO, я не закоренелый Вижуал Студиевец, я в ней только начал разбираться, например как увидеть ассемблерный листинг компилятора без вызова отладчика пока не понял (но я в отладчике смотрю и не переживаю). А вот то, что в gcc нельзя задавать голые функции - наверное действительно неудобно. Приходится наверное использовать макросы или вырезать прологи/эпилоги прямо из готового ассемблерного кода
Насчет разных ключей оптимизации - тоже хотел попробовать, но компилятор ругается на несовместимость ключей при указании оптимизации, надо с этим тоже разбираться. А насчет сохранения только нужных мне регистров - об этом и была речь в этом простом примере, теперь я могу сам определять какую часть контекста мне надо спасать - от нуля до полного, или положиться в этом на компилятор. Это очень развязывает руки, появляется ощущение что я сам пишу код (как было на чистом asm), и могу избавиться от помех компилятора при необходимости. Kastaneda, да, вы правы, просто я позволил себе вольно выразиться - в стек пихается много чего после передачи управления на метку начала функции, а сама передача осуществляется CALL-ом. В той книжке, которую я читаю, написано что можно передать RET параметр, который изменит указатель стека, по которому брать адрес возврата, без выталкивания из стека всего того, что в него было ранее засунуто. А можно изменить его вручную после вызова функции. Я это ещё не пробовал, но это первое что я сделаю, как приду с работы
0
|
18.03.2013, 14:09 | 10 |
0
|
18.03.2013, 14:09 | |
18.03.2013, 14:09 | |
Помогаю со студенческими работами здесь
10
ASM Вставки iDIV Delphi + asm(Вставки), строки. Asm вставки в AVR GCC Длинная арифметика (ASM-вставки в C++) Построчное выполнение asm-вставки в сишный код Не работает процессор pentium d 820 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |