Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Центр помощи > [asm&pascal] суммирование переменных |
Автор: Kirill89 1.7.2007, 23:04 | ||
Я почти не знаком с ассемблером, как сделать?:
Заранее спасибо! |
Автор: Kuvaldis 2.7.2007, 01:12 | ||
Kirill89,
Пояснение: в ASM нельзя напрямую работать с командами, в которых левый и правый операнды расположены в памяти (т.е. пересылка, арифметические команды и т.д.), что связано с кодированием команд в архитектуре процессора INTEL. Поэтому вместо временной переменной используем регистр eax (для 32-битных приложений), или ax (для 16-битных) далее складываем в регистре и заносим регистр в результат. Регистр - это ячейка памяти непосредственно в процессоре |
Автор: mr.Anderson 2.7.2007, 09:18 | ||
Kuvaldis, конечно, может, это лишнее в данном случае, но я тут в DRKB прочитал, что рекомендуется не делать ассемблерных вставок внутри процедур/функций, т.к. это снижает быстродействие. Мож, я и не прав, но имхо лучше было бы так:
|
Автор: Kuvaldis 2.7.2007, 10:36 | ||
mr.Anderson,
В общем, если функция вызывается где-нибудь в цикле, то лучше ее реализовать как ассемблерную вставку без вызова функции (типа inline). При вызове функции в программный стек заносится много лишней инфы, необходимой для выхода из функции (стековый фрейм): там и адрес возврата, и параметры, и локальные переменные. Это ЯВНО тормозит выполнение. Но, с другой стороны, увеличивается структурированность. ТАк что здесь нужно автору смотреть, что он хочет сделать. ![]() |
Автор: Kirill89 2.7.2007, 18:34 |
mr.Anderson, Kuvaldis, Спасибо! + вам ![]() |
Автор: Kirill89 2.7.2007, 20:23 |
оказалось это не всё :( Как на ассемблере сделать цикл loop? |
Автор: mr.Anderson 2.7.2007, 21:06 | ||
Пример:
Не проверял, но работать должно. |
Автор: Kirill89 2.7.2007, 22:22 | ||
сразу говорю, что не работает... Как сделать вложенный цикл? как получить текущее значение циклической переменной? Это cx? я правильно понял? |
Автор: mr.Anderson 2.7.2007, 23:02 | ||
Ффух... вот что значит в асме ни бум-бум... Еле написал. Процедура циклически прибавляет к 10 единицу. В итоге получаем 15. Переделай под себя.
|
Автор: Kirill89 3.7.2007, 00:24 | ||
mr.Anderson, ага, совсем не бум-бум... почти ничего не понял из твоего... творчества ![]()
Это надо сделать вставкой... Выручай, сделаешь это- будет ещё "+"... извини, что напрягаю... |
Автор: mr.Anderson 3.7.2007, 09:31 | ||
Да не бум-бум не вы, а я. ![]()
|
Автор: Kuvaldis 3.7.2007, 10:40 | ||
Объясняю принцип построения циклов на ассемблере. Есть встроенная команда loop, веденная в архитектуру INTEL еще с процессоров 8086, предназначенная для обработки циклов. Принцип работы: 1. Из регистра ecx вычитается 1 2. Если ecx != 0, то происходит переход по метке Прошу заметить, что ручками ничего вычитать не надо. Это делается на аппаратном уровне Далее: организация вложенных циклов Понятно, что для этого нам нужно где-то сохранять регистр-счетчик ecx внешнего цикла, пока работает внутренний. Для этого помещаем данный регистр в стек и перед 2-м лупом восстанавливаем. Смотри код Еще один момент: передача параметров. Написано var, т.е. идут адреса переменных. Значит, заполняем "адресные" регистры (для косвенной регистровой адресации) при помощи команды mov В общем, смотри, что тебе непонятно. Будем пробовать разбираться Код рабочий
|
Автор: mr.Anderson 3.7.2007, 12:07 |
Kuvaldis, а мне можно вопросы задать? Во-первых, почему используем именно edi в строчке 37. Во-вторых, нигде не видно, чтобы по коду edi увеличивался. Как же мы тогда получаем новых элемент массива? В-третьих, почему в строке 40 esi в квадратных скобках. Это означает, что помещаем не в регистр, а в то, что в нем находится? |
Автор: Kuvaldis 3.7.2007, 13:53 | ||||||||
mr.Anderson,
Это от старого кода осталось ![]()
Получаем новый элемент массива путем добавления к адресу начала, который в ebx размера эл-та массива (это 4 байта). Лучше использовать конечно что-либо типа TYPE, но во встроенный асм Delphi эта директива не включена
esi - регистр, который используется как указатель в прогах на асме. Т.е. запись mov [esi], 10 значит то же самое, что и *esi = 10 (разыменование указателя в С++) Вот подлизанный вариант кода (брал лишнее из выше выложенного, который тоже рабочий ![]()
|
Автор: Kirill89 3.7.2007, 19:27 |
Kuvaldis, mr.Anderson, вам обоим большое спасибо и по "+". Очень помогли. |