IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

 
 Ответить  Открыть новую тему 
> Приемы уменьшения размера ассемблерного кода
сообщение
Сообщение #1


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Несколько примеров под x86/real mode...

Примечание: далее под словосочетанием "регистр общего назначения" подразумевается один из регистров: ax, bx, cx, dx, si, di, sp, bp.

(1) Классика:
mov r,0 ; -> xor r,r

где r - регистр общего назначения;

Примечание: "бородатый" прием, получивший распространение в том или ином виде на многих архитектурах; в AVR он даже заслужил дополнительную мнемонику - "clr".

(2)
mov d,s ; -> xchg d,s

где d, s - регистры общего назначения;
замена применима в том случае, если значением s можно пожертвовать.

Примечание: на младших членах семейства x86 (I8088/I8086) инструкция "xchg" выполняется медленнее "mov".

(3)
mov r,a ; -> lea d,[a+b]
add r,b |

где
a - bx,bp или константа;
b - si, di или константа;
r - любой регистр общего назначения.

Примечание: кстати, многие ассемблеры автоматически заменяют "lea r,label" на "mov r,offset label" исходя из соображений, что настоящая инструкция "lea" в данном случае займет 4 байта, а "mov" - только 3.

(4) Загрузка константы в сегментный регистр:
mov ax,0A000h ; -> push 0A000h
mov es,ax     ;   pop es


Примечание: "push <константа>" появилась в системе команд x86 начиная с I80186.

(5) Получение адреса элемента массива по его индексу:
mov ax,ELEM_SIZE ; -> mov ax,ELEM_SIZE
mul index        ;   mul index
lea di,array     ;   add ax,offset array
add di,ax        ;   xchg di,ax

где
ELEM_SIZE - размер элемента массива,
index (регистр общего назначения или переменная в памяти) - индекс элемента, адрес которого нас интересует.

(6) Для особо ярых поклонников x86 и команд push/pop:
Если на входе в процедуру (или другой участок кода, от которого требуется сохранять, а затем восстанавливать значения некоторых регистров) сохраняется больше одного регистра, то последовательность "push"'ей можно заменить на "pusha", а "pop"'ов - на команду со звучным названием "popa".

Примечание: кстати, RISC-процессор SPARC при обращении к процедурам в большинстве случаев прекрасно обходится без технологии "толкай-тяни" благодаря использованию регистрового файла со скользящим окном, который в частности выполняет функции стека вызовов - в нем сохраняются адреса возврата, передаются параметры и хранятся локальные переменные.

May be continued... ;)

P.S. В дополнение - маленький пример, как это работает...


Прикрепленные файлы
Прикрепленный файл  flag.zip ( 1.44 килобайт ) Кол-во скачиваний: 388


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






...ещё достигается хорошая оптимизация при применении вместо команд обычного умножения(деления) сдвигов -оч хорошие результаты :p2:

Сообщение отредактировано: Анна -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Lonely_Raven
****

Группа: Пользователи
Сообщений: 640
Пол: Мужской

Репутация: -  1  +


Анна
на степени двойки


--------------------
Программа делает то что вы ей приказали а не то что бы ВАМ хотелось бы.
МЕРФИ
---------------------
RTFM - Read the fucking manual
---------------------
http://www.livejournal.com/users/lonley_raven/
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Бывалый
***

Группа: Пользователи
Сообщений: 180
Пол: Мужской

Репутация: -  2  +


Я еще со времен ПК8000 (на проце К580) задумывался, а почему не сделали вместо команд условного перехода типа JNZ, JZ, JC и т.д. просто условия (в виде префиксов например): IFNZ <команда> - мне кажется, так было бы удобнее, так как частенько условие нужно лишь для выполнения одной команды (только представьте: IFNZ DEC AX), а из-за этого приходится делать переход... а переходы по условию выглядели бы так: IFZ JMP adr. Однако так никто никогда не делал, из чего я заключаю, что это гораздо сложнее сделать при существующих архитектурах процессоров? (другой вариант - никто не догадался ;) ) С другой стороны - есть же префиксы-циклы REPNZ и т.д. unsure.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


К счастью, все не так уж плохо. В некоторых архитектурах встречаются инструкции условного пропуска следующих за ними инструкций. Так в AVR RISC это команды SBIC/SBIS (Skip if Bit in I/O register is Cleared/Set) и SBRC/SBRS (Skip if Bit in Register is Cleared/Set). Следует отметить, что в AVR слово состояния процессора доступно как регистр ввода/вывода, поэтому эта архитектура является реально существующей реализацией рассмотренного тобой случая.

Впрочем, архитектуры с ортогональной системой команд (в основном RISC-процессоры и их RISC-подобные предшественники, exempli gratia, LSI-11) всегда отличались ощутимо большей долей рациональности, чем классические CISC-семейства - постепенно распухающие от объема устаревших инструкций и сгибающиеся под весом новых (в "родимом" x86 легко обнаруживаются следы i8080, и даже i8008, не говоря уж о том, что Pentium 4 до сих пор полноценно поддерживает 16-битный реальный режим). К слову, RISC-архитектуры легко справляются с проблемами "накопления совместимости" путем разумного использования исключений для программной эмуляции устаревших инструкций.


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Прогрессор
****

Группа: Пользователи
Сообщений: 602
Пол: Мужской
Реальное имя: Михаил

Репутация: -  9  +


Вместо команды mov ax, 0 ,занимающей в памяти 5 байт, можно написать xor ax, ax , занимающую 1 байт. Хотя, это, наверное, общеизвестный факт, или нет? {Нам на лекции рассказали}
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Цитата(Atos @ 30.09.04 12:13)
Вместо команды mov ax, 0 ,занимающей в памяти 5 байт

В x86/real mode - 3 байта...


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Существует на удивление много способов применения инструкций cbw/cwd "не по прямому назначению". Вот как, например, можно посчитать абсолютную величину 16-битного целого без применения команд условного перехода. Пусть в ax - исходное число, тогда
        cwd
       or dx,1
       mul dx

или
        cwd
       xor ax,dx
       sub ax,dx

возвратит в ax его абсолютную величину. В основе подобных ухищрений лежит простое свойство этих команд возвращать 0 для положительных чисел и -1 - для отрицательных. Вот как можно реализовать аналог предложения Паскаля "if x < 0 then x := 0;":
        mov ax,x
       cwd
       not dx
       and ax,dx
       mov x,ax


"if x >= 320 then x := 0;":
        mov ax,x
       sub ax,320
       cwd
       and ax,dx
       and dx,320
       add ax,dx
       mov x,ax


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Бывалый
***

Группа: Пользователи
Сообщений: 180
Пол: Мужской

Репутация: -  2  +


xds
но ведь щас вроде как везде RISC-архитектура используется... я помню, первый раз увидел это слово (аббревиатуру) в описании первых AMD-процессоров... интересно, а можно программировать напрямую на микрокоде, в обход "интерпретатора" команд х86 ?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Цитата(P@sh@ @ 1.10.04 8:09)
но ведь щас вроде как везде RISC-архитектура используется...

Я имел в виду полноценные RISC-процессоры (SPARC, MIPS, PA-RISC, AVR и т. п.), т. е. те, у которых RISC-архитектура реализована на уровне системы команд - собственно там, где её польза действительно ощутима.


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 17:36
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name