Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Библиотеки MD5 и SHA1
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
toweroff
Кто-нибудь пользовал? Можете поделиться?

Пока нашел под MD5 и добился 25сек (@72MHz) для вычисления блока 64MB памяти, висящей на EMC, но может есть что-то более оптимизированное

Все вычисляемые блоки 100% выровнены по 64 байта (вроде для SHA было такое ограничение)
Rst7
Во-первых в штатном MD5 прилично оверхеда на подготовку данных блока - копирование в местный буфер и прочее. Во-вторых, сейчас навскидку не скажу, но помнится мне, что классический вариант не имеет никакой потуги к обустраиванию переменных при расчете хеша блока в регистрах - а в arm-режиме оно точно войдет и даст заметный прирост производительности, хотя, больше чем процентов на 30 прироста я бы не расчитывал.

С шаодын такие фокусы, к сожалению, не пройдут.
toweroff
Цитата(Rst7 @ Feb 11 2009, 22:35) *
Во-первых в штатном MD5 прилично оверхеда на подготовку данных блока


unsure.gif о как.. а по-подробнее об этом мжно? ARM три дня только как в руки взял smile.gif
В проекте планируется LPC2468

так... обнаружил буфер. Видать, не докопал... он объявлен как char. Если перелопатить это все под int - насколько (примерно, конечно) можно ожидать увеличени (или спада smile.gif ) производительности?
Rst7
Цитата
Если перелопатить это все под int


Я так понимаю, у Вас всегда круглое число блоков по 64 байта попадает на вход расчета? Если да, то надо убирать эту буферизацию вообще. Только в конце, после последнего блока подсовывать pad.

Это то, что касается прямых накладных расходов. По поводу распределения регистров я гляну завтра, если будут силы доползти до компа.
toweroff
Цитата(Rst7 @ Feb 11 2009, 23:19) *
Я так понимаю, у Вас всегда круглое число блоков по 64 байта попадает на вход расчета? Если да, то надо убирать эту буферизацию вообще. Только в конце, после последнего блока подсовывать pad.

Это то, что касается прямых накладных расходов. По поводу распределения регистров я гляну завтра, если будут силы доползти до компа.


да, всегда попадает. Спасибо, буду ждать
Rst7
Сейчас глянул по быстрому исходник мд5. Похоже, насчет 30 процентов я Вас здорово обманул. Все там хорошо, немного можно с бубном поплясать, но это даст отсилы выигрыш в единицы процентов.
Если очень интересует, могу завтра сделать. Но, чуда не будет sad.gif

Кстати, я надеюсь, компилятор Вами используется вменяемый и на максимальной оптимизации по скорости?

А, и еще. Процедуру расчета было бы правильно расположить во внутреннем озу. Тогда будет максимальное быстродействие.
toweroff
Цитата(Rst7 @ Feb 12 2009, 00:03) *
Сейчас глянул по быстрому исходник мд5. Похоже, насчет 30 процентов я Вас здорово обманул. Все там хорошо, немного можно с бубном поплясать, но это даст отсилы выигрыш в единицы процентов.
Если очень интересует, могу завтра сделать. Но, чуда не будет sad.gif


я вот тоже сижу танцую, но пока неалчно


Цитата(Rst7 @ Feb 12 2009, 00:03) *
Кстати, я надеюсь, компилятор Вами используется вменяемый и на максимальной оптимизации по скорости?


компилятор кейловский, гнушный пока не ставил. Оптимизация 2 уровень + галка Speed. На уровне 3 дает примерно 33с

Цитата(Rst7 @ Feb 12 2009, 00:03) *
А, и еще. Процедуру расчета было бы правильно расположить во внутреннем озу. Тогда будет максимальное быстродействие.


тык это надо перекинуть кусок внешней памяти (ну выделю я там под него килов 32), потом обработать... накладных расходов много, не считаете? 2к раз это делать
AlexandrY
Что-то больно хороший результат у вас получается.
Если считать, что MD5 считается на данных во внешней FLASH памяти (найти статическую RAM на такой объем не знаю где можно) и проц работает не из кэша, то результат должен быть раза в два хуже.
На SHA1 должно быть еще в 2-а раза медленнее.
Или объем в мегабитах все таки написан? biggrin.gif

А.., понял. Глянул тут ниже ваши изыскания. Вы в симуляторе считаете ?

Цитата(toweroff @ Feb 11 2009, 21:21) *
Кто-нибудь пользовал? Можете поделиться?

Пока нашел под MD5 и добился 25сек (@72MHz) для вычисления блока 64MB памяти, висящей на EMC, но может есть что-то более оптимизированное

Все вычисляемые блоки 100% выровнены по 64 байта (вроде для SHA было такое ограничение)
toweroff
Цитата(AlexandrY @ Feb 12 2009, 00:23) *
Что-то больно хороший результат у вас получается.
Если считать, что MD5 считается на данных во внешней FLASH памяти (найти статическую RAM на такой объем не знаю где можно) и проц работает не из кэша, то результат должен быть раза в два хуже.
На SHA1 должно быть еще в 2-а раза медленнее.
Или объем в мегабитах все таки написан? biggrin.gif

А.., понял. Глянул тут ниже ваши изыскания. Вы в симуляторе считаете ?


да, это симулятор, объем 64 мегаБАЙТА. В реале я несколько разочаруюсь? smile.gif

кстати... совсем забыл.. надо бы выставить задержки под внешнюю флеш, она на 110нс, ну может буферное чтение включить... но умеет ли это все правильно Keil просчитывать - вопрос

Rst7

Попробовал копировать во втутреннюю RAM куски по 32Кб... результат практически одинаков, хуже на 1.5сек (симулятор Keil, не девайс пока !!!)
Rst7
Цитата
Попробовал копировать во втутреннюю RAM куски по 32Кб...


Ненене smile.gif Только саму функцию надо было в озу разместить, чтобы выполнение шло из него. Как в кейле не знаю, в IAR'е используется модификатор __ramfunc, если мне не изменяет память.
toweroff
Цитата(Rst7 @ Feb 12 2009, 01:05) *
Ненене smile.gif Только саму функцию надо было в озу разместить, чтобы выполнение шло из него. Как в кейле не знаю, в IAR'е используется модификатор __ramfunc, если мне не изменяет память.


ок, разместил. Компилятор показывает, что все нормально, все функции md5 помещены с адреса 0х40000000 до какого-то там. Скорость не изменилась

опять же, это симулятор и черт его знает, как будет в реальном процессоре

Пока хочу все отладить, чтобы потом не сильно бодаться с железкой
AlexandrY
110 нс !?
Тогда еще процентов на 20 в худшую сторону подправьте результат.
MD5 очень чувствителен к скорости памяти из которой читаются данные.

А симулятор в Keil-е по умолчанию не учитывает вообще никаких задержек на шинах.
Перенос программы в RAM не даст практически ничего.
В LPC программа из FLASH выполняется не намного медленнее чем из RAM.
http://aly.ogmis.lt/Subjects/Tests/LPC/LPC.htm


Цитата(toweroff @ Feb 11 2009, 23:48) *
кстати... совсем забыл.. надо бы выставить задержки под внешнюю флеш, она на 110нс, ну может буферное чтение включить... но умеет ли это все правильно Keil просчитывать - вопрос
toweroff
Цитата(AlexandrY @ Feb 12 2009, 10:21) *
А симулятор в Keil-е по умолчанию не учитывает вообще никаких задержек на шинах.


можно по-подробнее? как снять эти умолчания и задать конфигурацию задержек (если это вообще можно, конечно)?
Rst7
Цитата
MD5 очень чувствителен к скорости памяти из которой читаются данные.


Ошибаетесь. Там всего одно считывание каждого слова. Главное, убрать буферизацию перед расчетом, вот она там скорости не прибавит ну никак.

Цитата
Перенос программы в RAM не даст практически ничего.


Даст. Процентов 10 в arm-режиме. Потому что сам расчет практически проводится в регистрах без особого доступа к переменным.

Пардон, считываний таки 4, а не 1.
AlexandrY
Правильно, только не слова, а байта, т.к. исходный массив над которым производятся вычисления может быть даже по словам не выровнен.
А алгоритм MD5 адаптированный к 32-х битным платформам оперирует длиными целыми по 4-е байта.
Итого как минимум вся внешняя память должна быть побайтно перекачана во внутреннюю в ходе вычислений.
Мои замеры показывают, что скорость чтения 64-х байтными блоками из внешней 16-и битной SRAM cо временем доступа 12 нс не превышает 12-16 Мбайт/сек у ARM9 на шине с частотой ~50 МГц, самым оптимизированным алгоритмом.
Чтение 64 Мбайт займет соответственно 4 сек, а из в 5-ть раз более медленной памяти соответсвенно 20 сек!
Так что в тормозах влияние памяти основное.

Цитата(Rst7 @ Feb 12 2009, 11:54) *
Ошибаетесь. Там всего одно считывание каждого слова. Главное, убрать буферизацию перед расчетом, вот она там скорости не прибавит ну никак.
Rst7
Цитата
Правильно, только не слова, а байта, т.к. исходный массив над которым производятся вычисления может быть даже по словам не выровнен.


В данном конкретном случае эту буферизацию можно выбросить.

Однако, я немного просмотрелся (все же 4 считывания), так что внести кеширование блока в расчет будет правильным ходом.

Кроме того, я сейчас не помню, LDR Rx,[PC+число] и аналогичная загрузка с автоинкрементом обычного регистра одно и то же по тактам, или нет? Если второй способ быстрее, то имеет смысл еще заменить загрузки констант в самом расчете.
AlexandrY
Не понял про буфферизацию biggrin.gif
Я говорю, что память читать ВНЕШНЮЮ надо всю по любому.
Если чел не сделает буфферизацию, ему придется вообще чуть ли не через каждый оператор к внешней памяти обращаться!
Никакого смысла разбираться сколько там времени будут выполняться операторы не имеет, к внешней памяти доступ идет через транзакции по AHB которым пофик какими операторами вы их вызвали.
Продуктивней уж ковыряться в настройках контроллера внешней памяти

На всяк случай приведу исходник главной функции, чтоб проверить об одном и том же ли мы говорим.
Здесь в качестве аргумент data[64] передается указатель на данные во внешней памяти.

Код
void md5_process( md5_context *ctx, uint8 data[64] )
{
  uint32 X[16], A, B, C, D;

  GET_UINT32( X[0],  data,  0 );
  GET_UINT32( X[1],  data,  4 );
  GET_UINT32( X[2],  data,  8 );
  GET_UINT32( X[3],  data, 12 );
  GET_UINT32( X[4],  data, 16 );
  GET_UINT32( X[5],  data, 20 );
  GET_UINT32( X[6],  data, 24 );
  GET_UINT32( X[7],  data, 28 );
  GET_UINT32( X[8],  data, 32 );
  GET_UINT32( X[9],  data, 36 );
  GET_UINT32( X[10], data, 40 );
  GET_UINT32( X[11], data, 44 );
  GET_UINT32( X[12], data, 48 );
  GET_UINT32( X[13], data, 52 );
  GET_UINT32( X[14], data, 56 );
  GET_UINT32( X[15], data, 60 );

#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))

#define P(a,b,c,d,k,s,t)                                \
{                                                       \
    a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
}

  A = ctx->state[0];
  B = ctx->state[1];
  C = ctx->state[2];
  D = ctx->state[3];

#define F(x,y,z) (z ^ (x & (y ^ z)))

  P( A, B, C, D,  0,  7, 0xD76AA478 );
  P( D, A, B, C,  1, 12, 0xE8C7B756 );
  P( C, D, A, B,  2, 17, 0x242070DB );
  P( B, C, D, A,  3, 22, 0xC1BDCEEE );
  P( A, B, C, D,  4,  7, 0xF57C0FAF );
  P( D, A, B, C,  5, 12, 0x4787C62A );
  P( C, D, A, B,  6, 17, 0xA8304613 );
  P( B, C, D, A,  7, 22, 0xFD469501 );
  P( A, B, C, D,  8,  7, 0x698098D8 );
  P( D, A, B, C,  9, 12, 0x8B44F7AF );
  P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
  P( B, C, D, A, 11, 22, 0x895CD7BE );
  P( A, B, C, D, 12,  7, 0x6B901122 );
  P( D, A, B, C, 13, 12, 0xFD987193 );
  P( C, D, A, B, 14, 17, 0xA679438E );
  P( B, C, D, A, 15, 22, 0x49B40821 );

#undef F

#define F(x,y,z) (y ^ (z & (x ^ y)))

  P( A, B, C, D,  1,  5, 0xF61E2562 );
  P( D, A, B, C,  6,  9, 0xC040B340 );
  P( C, D, A, B, 11, 14, 0x265E5A51 );
  P( B, C, D, A,  0, 20, 0xE9B6C7AA );
  P( A, B, C, D,  5,  5, 0xD62F105D );
  P( D, A, B, C, 10,  9, 0x02441453 );
  P( C, D, A, B, 15, 14, 0xD8A1E681 );
  P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
  P( A, B, C, D,  9,  5, 0x21E1CDE6 );
  P( D, A, B, C, 14,  9, 0xC33707D6 );
  P( C, D, A, B,  3, 14, 0xF4D50D87 );
  P( B, C, D, A,  8, 20, 0x455A14ED );
  P( A, B, C, D, 13,  5, 0xA9E3E905 );
  P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
  P( C, D, A, B,  7, 14, 0x676F02D9 );
  P( B, C, D, A, 12, 20, 0x8D2A4C8A );

#undef F

#define F(x,y,z) (x ^ y ^ z)

  P( A, B, C, D,  5,  4, 0xFFFA3942 );
  P( D, A, B, C,  8, 11, 0x8771F681 );
  P( C, D, A, B, 11, 16, 0x6D9D6122 );
  P( B, C, D, A, 14, 23, 0xFDE5380C );
  P( A, B, C, D,  1,  4, 0xA4BEEA44 );
  P( D, A, B, C,  4, 11, 0x4BDECFA9 );
  P( C, D, A, B,  7, 16, 0xF6BB4B60 );
  P( B, C, D, A, 10, 23, 0xBEBFBC70 );
  P( A, B, C, D, 13,  4, 0x289B7EC6 );
  P( D, A, B, C,  0, 11, 0xEAA127FA );
  P( C, D, A, B,  3, 16, 0xD4EF3085 );
  P( B, C, D, A,  6, 23, 0x04881D05 );
  P( A, B, C, D,  9,  4, 0xD9D4D039 );
  P( D, A, B, C, 12, 11, 0xE6DB99E5 );
  P( C, D, A, B, 15, 16, 0x1FA27CF8 );
  P( B, C, D, A,  2, 23, 0xC4AC5665 );

#undef F

#define F(x,y,z) (y ^ (x | ~z))

  P( A, B, C, D,  0,  6, 0xF4292244 );
  P( D, A, B, C,  7, 10, 0x432AFF97 );
  P( C, D, A, B, 14, 15, 0xAB9423A7 );
  P( B, C, D, A,  5, 21, 0xFC93A039 );
  P( A, B, C, D, 12,  6, 0x655B59C3 );
  P( D, A, B, C,  3, 10, 0x8F0CCC92 );
  P( C, D, A, B, 10, 15, 0xFFEFF47D );
  P( B, C, D, A,  1, 21, 0x85845DD1 );
  P( A, B, C, D,  8,  6, 0x6FA87E4F );
  P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
  P( C, D, A, B,  6, 15, 0xA3014314 );
  P( B, C, D, A, 13, 21, 0x4E0811A1 );
  P( A, B, C, D,  4,  6, 0xF7537E82 );
  P( D, A, B, C, 11, 10, 0xBD3AF235 );
  P( C, D, A, B,  2, 15, 0x2AD7D2BB );
  P( B, C, D, A,  9, 21, 0xEB86D391 );

#undef F

  ctx->state[0] += A;
  ctx->state[1] += B;
  ctx->state[2] += C;
  ctx->state[3] += D;
}


Цитата(Rst7 @ Feb 12 2009, 14:08) *
В данном конкретном случае эту буферизацию можно выбросить.

Однако, я немного просмотрелся (все же 4 считывания), так что внести кеширование блока в расчет будет правильным ходом.

Кроме того, я сейчас не помню, LDR Rx,[PC+число] и аналогичная загрузка с автоинкрементом обычного регистра одно и то же по тактам, или нет? Если второй способ быстрее, то имеет смысл еще заменить загрузки констант в самом расчете.
toweroff
О во что небольшой вопрос вылился smile.gif

AlexandrY, контроллер я настраиваю на 32-разрядную шину. Пока никакой буферизации чтения нет, все равно отлаживать по скорости придется на готовом девайсе - попытаюсь использовать буферное чтение из флеш (благо она это поддерживает)

Пока вкрутил еще библиотеки SHA1 и MD5 от MatrixSSL (скачать тут

Запуск в симуляторе Keil показывает время 25сек для MD5 и 73сек для SHA1

В результате, если уложусь в 2.5мин на реальном девайсе - будет очень даже хорошо. Но все равно любые мысли по оптимизации приветствуются smile.gif

Всем спасибо!
Rst7
Вообщем, правильный MD5 для заказанных условий (выровненные круглые блоки) должен выглядеть для ARM7 примерно так
CODE

/* F, G and H are basic MD5 functions: selection, majority, parity */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

/* ROTATE_LEFT rotates x left n bits */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s, ac) \
{(a) += F ((b), ©, (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{(a) += G ((b), ©, (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{(a) += H ((b), ©, (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{(a) += I ((b), ©, (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}


__ramfunc __arm void ProcessMD5byBlock(unsigned int *dst, unsigned int *src, int num_of_blocks)
{
unsigned int ctx0=0x67452301;
unsigned int ctx1=0xefcdab89;
unsigned int ctx2=0x98badcfe;
unsigned int ctx3=0x10325476;
unsigned int bitsize=num_of_blocks*8;
num_of_blocks++;
do
{
volatile unsigned int in[16];
unsigned int a,b,c,d;
a=ctx0;
b=ctx1;
c=ctx2;
d=ctx3;
if (num_of_blocks==1)
{
//Prepare padding
src=(unsigned int*)in;
in[0]=0x80;
in[1]=0;
in[2]=0;
in[3]=0;
in[4]=0;
in[5]=0;
in[6]=0;
in[7]=0;
in[8]=0;
in[9]=0;
in[10]=0;
in[11]=0;
in[12]=0;
in[13]=0;
in[14]=bitsize;
in[15]=0;
}
/* Round 1 */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0]=*src++, S11, 3614090360); /* 1 */
FF ( d, a, b, c, in[ 1]=*src++, S12, 3905402710); /* 2 */
FF ( c, d, a, b, in[ 2]=*src++, S13, 606105819); /* 3 */
FF ( b, c, d, a, in[ 3]=*src++, S14, 3250441966); /* 4 */
FF ( a, b, c, d, in[ 4]=*src++, S11, 4118548399); /* 5 */
FF ( d, a, b, c, in[ 5]=*src++, S12, 1200080426); /* 6 */
FF ( c, d, a, b, in[ 6]=*src++, S13, 2821735955); /* 7 */
FF ( b, c, d, a, in[ 7]=*src++, S14, 4249261313); /* 8 */
FF ( a, b, c, d, in[ 8]=*src++, S11, 1770035416); /* 9 */
FF ( d, a, b, c, in[ 9]=*src++, S12, 2336552879); /* 10 */
FF ( c, d, a, b, in[10]=*src++, S13, 4294925233); /* 11 */
FF ( b, c, d, a, in[11]=*src++, S14, 2304563134); /* 12 */
FF ( a, b, c, d, in[12]=*src++, S11, 1804603682); /* 13 */
FF ( d, a, b, c, in[13]=*src++, S12, 4254626195); /* 14 */
FF ( c, d, a, b, in[14]=*src++, S13, 2792965006); /* 15 */
FF ( b, c, d, a, in[15]=*src++, S14, 1236535329); /* 16 */

/* Round 2 */
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */

/* Round 3 */
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */
HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */
HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */
HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */

/* Round 4 */
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */
II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */
II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */
ctx0+=a;
ctx1+=b;
ctx2+=c;
ctx3+=d;
}
while(--num_of_blocks);
*dst++=ctx0;
*dst++=ctx1;
*dst++=ctx2;
*dst++=ctx3;
}


И результат компиляции IAR 4.42
CODE

//////////////////////////////////////////////////////////////////////////////
// /
// IAR ARM ANSI C/C++ Compiler V4.42A/W32 EVALUATION 12/Feb/2009 17:17:08 /
// Copyright 1999-2005 IAR Systems. All rights reserved. /
// /
// Cpu mode = interwork /
// Endian = little /
// Stack alignment = 4 /
// Source file = E:\CodesArm\md5.c /
// Command line = E:\CodesArm\md5.c -lCN E:\CodesArm\Release\List\ /
// -lA E:\CodesArm\Release\List\ -o /
// E:\CodesArm\Release\Obj\ -s9 --no_code_motion /
// --no_clustering --cpu_mode arm --endian little /
// --cpu ARM7TDMI-S --stack_align 4 --interwork -e /
// --fpu None --dlib_config /
// D:\IAR_ARM_442A\arm\LIB\dl4tpainl8n.h -I /
// D:\IAR_ARM_442A\arm\INC\ --inline_threshold=2 /
// List file = E:\CodesArm\Release\List\md5.s79 /
// /
// /
//////////////////////////////////////////////////////////////////////////////

NAME md5

RTMODEL "StackAlign4", "USED"
RTMODEL "__cpu_mode", "__pcs__interwork"
RTMODEL "__data_model", "absolute"
RTMODEL "__endian", "little"
RTMODEL "__rt_version", "6"

RSEG CSTACK:DATA:NOROOT(2)

PUBWEAK `?*?CODE_ID`
MULTWEAK ??ProcessMD5byBlock??rT
PUBWEAK ?init?tab?CODE_I
PUBLIC ProcessMD5byBlock
FUNCTION ProcessMD5byBlock,0203H
LOCFRAME CSTACK, 108, STACK

CFI Names cfiNames0
CFI StackFrame CFA R13 HUGEDATA
CFI Resource R0:32, R1:32, R2:32, R3:32, R4:32, R5:32, R6:32, R7:32
CFI Resource R8:32, R9:32, R10:32, R11:32, R12:32, CPSR:32, R13:32
CFI Resource R14:32, SPSR:32
CFI VirtualResource ?RET:32
CFI EndNames cfiNames0

CFI Common cfiCommon0 Using cfiNames0
CFI CodeAlign 2
CFI DataAlign 4
CFI ReturnAddress ?RET CODE
CFI CFA R13+0
CFI R0 Undefined
CFI R1 Undefined
CFI R2 Undefined
CFI R3 Undefined
CFI R4 SameValue
CFI R5 SameValue
CFI R6 SameValue
CFI R7 SameValue
CFI R8 SameValue
CFI R9 SameValue
CFI R10 SameValue
CFI R11 SameValue
CFI R12 Undefined
CFI CPSR SameValue
CFI R14 Undefined
CFI SPSR SameValue
CFI ?RET R14
CFI EndCommon cfiCommon0


CFI Common cfiCommon1 Using cfiNames0
CFI CodeAlign 4
CFI DataAlign 4
CFI ReturnAddress ?RET CODE
CFI CFA R13+0
CFI R0 Undefined
CFI R1 Undefined
CFI R2 Undefined
CFI R3 Undefined
CFI R4 SameValue
CFI R5 SameValue
CFI R6 SameValue
CFI R7 SameValue
CFI R8 SameValue
CFI R9 SameValue
CFI R10 SameValue
CFI R11 SameValue
CFI R12 Undefined
CFI CPSR SameValue
CFI R14 Undefined
CFI SPSR SameValue
CFI ?RET R14
CFI EndCommon cfiCommon1

ProcessMD5byBlock SYMBOL "ProcessMD5byBlock"
??ProcessMD5byBlock??rT SYMBOL "??rT", ProcessMD5byBlock


RSEG CODE_I:CODE:NOROOT(2)
CFI Block cfiBlock0 Using cfiCommon0
CFI NoFunction
THUMB
??ProcessMD5byBlock??rT:
BX PC
Nop
CFI EndBlock cfiBlock0
REQUIRE ProcessMD5byBlock
// E:\CodesArm\md5.c
// 1 /* F, G and H are basic MD5 functions: selection, majority, parity */
// 2 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
// 3 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
// 4 #define H(x, y, z) ((x) ^ (y) ^ (z))
// 5 #define I(x, y, z) ((y) ^ ((x) | (~z)))
// 6
// 7 /* ROTATE_LEFT rotates x left n bits */
// 8 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
// 9
// 10 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
// 11 /* Rotation is separate from addition to prevent recomputation */
// 12 #define FF(a, b, c, d, x, s, ac) \
// 13 {(a) += F ((b), ©, (d)) + (x) + (unsigned int)(ac); \
// 14 (a) = ROTATE_LEFT ((a), (s)); \
// 15 (a) += (b); \
// 16 }
// 17 #define GG(a, b, c, d, x, s, ac) \
// 18 {(a) += G ((b), ©, (d)) + (x) + (unsigned int)(ac); \
// 19 (a) = ROTATE_LEFT ((a), (s)); \
// 20 (a) += (b); \
// 21 }
// 22 #define HH(a, b, c, d, x, s, ac) \
// 23 {(a) += H ((b), ©, (d)) + (x) + (unsigned int)(ac); \
// 24 (a) = ROTATE_LEFT ((a), (s)); \
// 25 (a) += (b); \
// 26 }
// 27 #define II(a, b, c, d, x, s, ac) \
// 28 {(a) += I ((b), ©, (d)) + (x) + (unsigned int)(ac); \
// 29 (a) = ROTATE_LEFT ((a), (s)); \
// 30 (a) += (b); \
// 31 }
// 32
// 33

RSEG CODE_I:CODE:NOROOT(2)
CFI Block cfiBlock1 Using cfiCommon1
CFI Function ProcessMD5byBlock
ARM
// 34 __ramfunc __arm void ProcessMD5byBlock(unsigned int *dst, unsigned int *src, int num_of_blocks)
// 35 {
ProcessMD5byBlock:
PUSH {R0,R4-R11,LR}
CFI ?RET Frame(CFA, -4)
CFI R11 Frame(CFA, -8)
CFI R10 Frame(CFA, -12)
CFI R9 Frame(CFA, -16)
CFI R8 Frame(CFA, -20)
CFI R7 Frame(CFA, -24)
CFI R6 Frame(CFA, -28)
CFI R5 Frame(CFA, -32)
CFI R4 Frame(CFA, -36)
CFI CFA R13+40
SUB SP,SP,#+68
CFI CFA R13+108
// 36 unsigned int ctx0=0x67452301;
LDR R0,??ProcessMD5byBlock_0 ;; 0x67452301
// 37 unsigned int ctx1=0xefcdab89;
LDR R3,??ProcessMD5byBlock_0+0x4 ;; 0xffffffffefcdab89
// 38 unsigned int ctx2=0x98badcfe;
MVN R12,R0
// 39 unsigned int ctx3=0x10325476;
MVN R4,R3
// 40 unsigned int bitsize=num_of_blocks*8;
LSL R6,R2,#+3
STR R6,[SP, #+64]
// 41 num_of_blocks++;
ADD R2,R2,#+1
// 42 do
// 43 {
// 44 volatile unsigned int in[16];
// 45 unsigned int a,b,c,d;
// 46 a=ctx0;
// 47 b=ctx1;
// 48 c=ctx2;
// 49 d=ctx3;
// 50 if (num_of_blocks==1)
??ProcessMD5byBlock_1:
CMP R2,#+1
BNE ??ProcessMD5byBlock_2
// 51 {
// 52 //Ãîòîâèì ïàääèíã
// 53 src=(unsigned int*)in;
MOV R1,SP
// 54 in[0]=0x80;
MOV R6,#+128
STR R6,[SP, #+0]
// 55 in[1]=0;
MOV R5,#+0
STR R5,[SP, #+4]
// 56 in[2]=0;
STR R5,[SP, #+8]
// 57 in[3]=0;
STR R5,[SP, #+12]
// 58 in[4]=0;
STR R5,[SP, #+16]
// 59 in[5]=0;
STR R5,[SP, #+20]
// 60 in[6]=0;
STR R5,[SP, #+24]
// 61 in[7]=0;
STR R5,[SP, #+28]
// 62 in[8]=0;
STR R5,[SP, #+32]
// 63 in[9]=0;
STR R5,[SP, #+36]
// 64 in[10]=0;
STR R5,[SP, #+40]
// 65 in[11]=0;
STR R5,[SP, #+44]
// 66 in[12]=0;
STR R5,[SP, #+48]
// 67 in[13]=0;
STR R5,[SP, #+52]
// 68 in[14]=bitsize;
LDR R7,[SP, #+64]
STR R7,[SP, #+56]
// 69 in[15]=0;
STR R5,[SP, #+60]
// 70 }
// 71 /* Round 1 */
// 72 #define S11 7
// 73 #define S12 12
// 74 #define S13 17
// 75 #define S14 22
// 76 FF ( a, b, c, d, in[ 0]=*src++, S11, 3614090360); /* 1 */
??ProcessMD5byBlock_2:
LDR R5,[R1], #+4
STR R5,[SP, #+0]
AND R6,R12,R3
BIC R7,R4,R3
ORR R6,R7,R6
ADD R6,R6,R0
ADD R5,R5,R6
LDR R6,??ProcessMD5byBlock_0+0x8 ;; 0xffffffffd76aa478
ADD R5,R6,R5
ADD R7,R3,R5, ROR #+25
// 77 FF ( d, a, b, c, in[ 1]=*src++, S12, 3905402710); /* 2 */
LDR R5,[R1], #+4
STR R5,[SP, #+4]
AND R6,R3,R7
BIC R8,R12,R7
ORR R6,R8,R6
ADD R6,R6,R4
ADD R5,R5,R6
LDR R6,??ProcessMD5byBlock_0+0xC ;; 0xffffffffe8c7b756
ADD R5,R6,R5
ADD R8,R7,R5, ROR #+20
// 78 FF ( c, d, a, b, in[ 2]=*src++, S13, 606105819); /* 3 */
LDR R5,[R1], #+4
STR R5,[SP, #+8]
AND R6,R7,R8
BIC R9,R3,R8
ORR R6,R9,R6
ADD R6,R6,R12
ADD R5,R5,R6
LDR R6,??ProcessMD5byBlock_0+0x10 ;; 0x242070db
ADD R5,R6,R5
ADD R5,R8,R5, ROR #+15
// 79 FF ( b, c, d, a, in[ 3]=*src++, S14, 3250441966); /* 4 */
LDR R6,[R1], #+4
STR R6,[SP, #+12]
AND R9,R8,R5
BIC R10,R7,R5
ORR R9,R10,R9
ADD R9,R9,R3
ADD R6,R6,R9
LDR R9,??ProcessMD5byBlock_0+0x14 ;; 0xffffffffc1bdceee
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+10
// 80 FF ( a, b, c, d, in[ 4]=*src++, S11, 4118548399); /* 5 */
LDR R9,[R1], #+4
STR R9,[SP, #+16]
AND R10,R5,R6
BIC R11,R8,R6
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x18 ;; 0xfffffffff57c0faf
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+25
// 81 FF ( d, a, b, c, in[ 5]=*src++, S12, 1200080426); /* 6 */
LDR R9,[R1], #+4
STR R9,[SP, #+20]
AND R10,R6,R7
BIC R11,R5,R7
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x1C ;; 0x4787c62a
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+20
// 82 FF ( c, d, a, b, in[ 6]=*src++, S13, 2821735955); /* 7 */
LDR R9,[R1], #+4
STR R9,[SP, #+24]
AND R10,R7,R8
BIC R11,R6,R8
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x20 ;; 0xffffffffa8304613
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+15
// 83 FF ( b, c, d, a, in[ 7]=*src++, S14, 4249261313); /* 8 */
LDR R9,[R1], #+4
STR R9,[SP, #+28]
AND R10,R8,R5
BIC R11,R7,R5
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x24 ;; 0xfffffffffd469501
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+10
// 84 FF ( a, b, c, d, in[ 8]=*src++, S11, 1770035416); /* 9 */
LDR R9,[R1], #+4
STR R9,[SP, #+32]
AND R10,R5,R6
BIC R11,R8,R6
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x28 ;; 0x698098d8
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+25
// 85 FF ( d, a, b, c, in[ 9]=*src++, S12, 2336552879); /* 10 */
LDR R9,[R1], #+4
STR R9,[SP, #+36]
AND R10,R6,R7
BIC R11,R5,R7
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x2C ;; 0xffffffff8b44f7af
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+20
// 86 FF ( c, d, a, b, in[10]=*src++, S13, 4294925233); /* 11 */
LDR R9,[R1], #+4
STR R9,[SP, #+40]
AND R10,R7,R8
BIC R11,R6,R8
ORR R10,R11,R10
ADD R9,R9,R10
MVN R10,#+78
BIC R10,R10,#0xA400
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+15
// 87 FF ( b, c, d, a, in[11]=*src++, S14, 2304563134); /* 12 */
LDR R9,[R1], #+4
STR R9,[SP, #+44]
AND R10,R8,R5
BIC R11,R7,R5
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x30 ;; 0xffffffff895cd7be
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+10
// 88 FF ( a, b, c, d, in[12]=*src++, S11, 1804603682); /* 13 */
LDR R9,[R1], #+4
STR R9,[SP, #+48]
AND R10,R5,R6
BIC R11,R8,R6
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x34 ;; 0x6b901122
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+25
// 89 FF ( d, a, b, c, in[13]=*src++, S12, 4254626195); /* 14 */
LDR R9,[R1], #+4
STR R9,[SP, #+52]
AND R10,R6,R7
BIC R11,R5,R7
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x38 ;; 0xfffffffffd987193
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+20
// 90 FF ( c, d, a, b, in[14]=*src++, S13, 2792965006); /* 15 */
LDR R9,[R1], #+4
STR R9,[SP, #+56]
AND R10,R7,R8
BIC R11,R6,R8
ORR R10,R11,R10
ADD R9,R9,R10
LDR R10,??ProcessMD5byBlock_0+0x3C ;; 0xffffffffa679438e
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+15
// 91 FF ( b, c, d, a, in[15]=*src++, S14, 1236535329); /* 16 */
LDR R10,[R1], #+4
STR R10,[SP, #+60]
MVN R9,R5
AND R11,R8,R5
AND LR,R7,R9
ORR R11,LR,R11
ADD R10,R10,R11
LDR R11,??ProcessMD5byBlock_0+0x40 ;; 0x49b40821
ADD R10,R11,R10
ADD R6,R10,R6
ADD R6,R5,R6, ROR #+10
// 92
// 93 /* Round 2 */
// 94 #define S21 5
// 95 #define S22 9
// 96 #define S23 14
// 97 #define S24 20
// 98 GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */
AND R10,R8,R6
BIC R11,R5,R8
ORR R10,R11,R10
LDR R11,[SP, #+4]
ADD R10,R11,R10
LDR R11,??ProcessMD5byBlock_0+0x44 ;; 0xfffffffff61e2562
ADD R10,R11,R10
ADD R7,R10,R7
ADD R7,R6,R7, ROR #+27
// 99 GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */
AND R10,R5,R7
AND R9,R9,R6
ORR R9,R9,R10
LDR R10,[SP, #+24]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x48 ;; 0xffffffffc040b340
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+23
// 100 GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */
AND R9,R6,R8
BIC R10,R7,R6
ORR R9,R10,R9
LDR R10,[SP, #+44]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x4C ;; 0x265e5a51
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+18
// 101 GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */
AND R9,R7,R5
BIC R10,R8,R7
ORR R9,R10,R9
LDR R10,[SP, #+0]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x50 ;; 0xffffffffe9b6c7aa
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+12
// 102 GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */
AND R9,R8,R6
BIC R10,R5,R8
ORR R9,R10,R9
LDR R10,[SP, #+20]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x54 ;; 0xffffffffd62f105d
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+27
// 103 GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */
AND R9,R5,R7
BIC R10,R6,R5
ORR R9,R10,R9
LDR R10,[SP, #+40]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x58 ;; 0x2441453
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+23
// 104 GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */
AND R9,R6,R8
BIC R10,R7,R6
ORR R9,R10,R9
LDR R10,[SP, #+60]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x5C ;; 0xffffffffd8a1e681
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+18
// 105 GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */
AND R9,R7,R5
BIC R10,R8,R7
ORR R9,R10,R9
LDR R10,[SP, #+16]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x60 ;; 0xffffffffe7d3fbc8
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+12
// 106 GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */
AND R9,R8,R6
BIC R10,R5,R8
ORR R9,R10,R9
LDR R10,[SP, #+36]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x64 ;; 0x21e1cde6
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+27
// 107 GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */
AND R9,R5,R7
BIC R10,R6,R5
ORR R9,R10,R9
LDR R10,[SP, #+56]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x68 ;; 0xffffffffc33707d6
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+23
// 108 GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */
AND R9,R6,R8
BIC R10,R7,R6
ORR R9,R10,R9
LDR R10,[SP, #+12]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x6C ;; 0xfffffffff4d50d87
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+18
// 109 GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */
AND R9,R7,R5
BIC R10,R8,R7
ORR R9,R10,R9
LDR R10,[SP, #+32]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x70 ;; 0x455a14ed
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+12
// 110 GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */
AND R9,R8,R6
BIC R10,R5,R8
ORR R9,R10,R9
LDR R10,[SP, #+52]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x74 ;; 0xffffffffa9e3e905
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+27
// 111 GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */
AND R9,R5,R7
BIC R10,R6,R5
ORR R9,R10,R9
LDR R10,[SP, #+8]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x78 ;; 0xfffffffffcefa3f8
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+23
// 112 GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */
AND R9,R6,R8
BIC R10,R7,R6
ORR R9,R10,R9
LDR R10,[SP, #+28]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x7C ;; 0x676f02d9
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+18
// 113 GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */
AND R9,R7,R5
BIC R10,R8,R7
ORR R9,R10,R9
LDR R10,[SP, #+48]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x80 ;; 0xffffffff8d2a4c8a
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+12
// 114
// 115 /* Round 3 */
// 116 #define S31 4
// 117 #define S32 11
// 118 #define S33 16
// 119 #define S34 23
// 120 HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */
EOR R9,R5,R6
EOR R9,R8,R9
LDR R10,[SP, #+20]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x84 ;; 0xfffffffffffa3942
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+28
// 121 HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */
EOR R9,R6,R7
EOR R9,R5,R9
LDR R10,[SP, #+32]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x88 ;; 0xffffffff8771f681
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+21
// 122 HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */
EOR R9,R7,R8
EOR R9,R6,R9
LDR R10,[SP, #+44]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x8C ;; 0x6d9d6122
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+16
// 123 HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */
EOR R9,R8,R5
EOR R9,R7,R9
LDR R10,[SP, #+56]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x90 ;; 0xfffffffffde5380c
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+9
// 124 HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */
EOR R9,R5,R6
EOR R9,R8,R9
LDR R10,[SP, #+4]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x94 ;; 0xffffffffa4beea44
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+28
// 125 HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */
EOR R9,R6,R7
EOR R9,R5,R9
LDR R10,[SP, #+16]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x98 ;; 0x4bdecfa9
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+21
// 126 HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */
EOR R9,R7,R8
EOR R9,R6,R9
LDR R10,[SP, #+28]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x9C ;; 0xfffffffff6bb4b60
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+16
// 127 HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */
EOR R9,R8,R5
EOR R9,R7,R9
LDR R10,[SP, #+40]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xA0 ;; 0xffffffffbebfbc70
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+9
// 128 HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */
EOR R9,R5,R6
EOR R9,R8,R9
LDR R10,[SP, #+52]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xA4 ;; 0x289b7ec6
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+28
// 129 HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */
EOR R9,R6,R7
EOR R9,R5,R9
LDR R10,[SP, #+0]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xA8 ;; 0xffffffffeaa127fa
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+21
// 130 HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */
EOR R9,R7,R8
EOR R9,R6,R9
LDR R10,[SP, #+12]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xAC ;; 0xffffffffd4ef3085
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+16
// 131 HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */
EOR R9,R8,R5
EOR R9,R7,R9
LDR R10,[SP, #+24]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xB0 ;; 0x4881d05
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+9
// 132 HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */
EOR R9,R5,R6
EOR R9,R8,R9
LDR R10,[SP, #+36]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xB4 ;; 0xffffffffd9d4d039
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+28
// 133 HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */
EOR R9,R6,R7
EOR R9,R5,R9
LDR R10,[SP, #+48]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xB8 ;; 0xffffffffe6db99e5
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+21
// 134 HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */
EOR R9,R7,R8
EOR R9,R6,R9
LDR R10,[SP, #+60]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xBC ;; 0x1fa27cf8
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+16
// 135 HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */
EOR R9,R8,R5
EOR R9,R7,R9
LDR R10,[SP, #+8]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xC0 ;; 0xffffffffc4ac5665
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+9
// 136
// 137 /* Round 4 */
// 138 #define S41 6
// 139 #define S42 10
// 140 #define S43 15
// 141 #define S44 21
// 142 II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */
MVN R9,R8
ORR R9,R9,R6
EOR R9,R9,R5
LDR R10,[SP, #+0]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xC4 ;; 0xfffffffff4292244
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+26
// 143 II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */
MVN R9,R5
ORR R9,R9,R7
EOR R9,R9,R6
LDR R10,[SP, #+28]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xC8 ;; 0x432aff97
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+22
// 144 II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */
MVN R9,R6
ORR R9,R9,R8
EOR R9,R9,R7
LDR R10,[SP, #+56]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xCC ;; 0xffffffffab9423a7
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+17
// 145 II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */
MVN R9,R7
ORR R9,R9,R5
EOR R9,R9,R8
LDR R10,[SP, #+20]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xD0 ;; 0xfffffffffc93a039
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+11
// 146 II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */
MVN R9,R8
ORR R9,R9,R6
EOR R9,R9,R5
LDR R10,[SP, #+48]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xD4 ;; 0x655b59c3
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+26
// 147 II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */
MVN R9,R5
ORR R9,R9,R7
EOR R9,R9,R6
LDR R10,[SP, #+12]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xD8 ;; 0xffffffff8f0ccc92
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+22
// 148 II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */
MVN R9,R6
ORR R9,R9,R8
EOR R9,R9,R7
LDR R10,[SP, #+40]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xDC ;; 0xffffffffffeff47d
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+17
// 149 II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */
MVN R9,R7
ORR R9,R9,R5
EOR R9,R9,R8
LDR R10,[SP, #+4]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xE0 ;; 0xffffffff85845dd1
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+11
// 150 II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */
MVN R9,R8
ORR R9,R9,R6
EOR R9,R9,R5
LDR R10,[SP, #+32]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xE4 ;; 0x6fa87e4f
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+26
// 151 II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */
MVN R9,R5
ORR R9,R9,R7
EOR R9,R9,R6
LDR R10,[SP, #+60]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xE8 ;; 0xfffffffffe2ce6e0
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+22
// 152 II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */
MVN R9,R6
ORR R9,R9,R8
EOR R9,R9,R7
LDR R10,[SP, #+24]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xEC ;; 0xffffffffa3014314
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+17
// 153 II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */
MVN R9,R7
ORR R9,R9,R5
EOR R9,R9,R8
LDR R10,[SP, #+52]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xF0 ;; 0x4e0811a1
ADD R9,R10,R9
ADD R6,R9,R6
ADD R6,R5,R6, ROR #+11
// 154 II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */
MVN R9,R8
ORR R9,R9,R6
EOR R9,R9,R5
LDR R10,[SP, #+16]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xF4 ;; 0xfffffffff7537e82
ADD R9,R10,R9
ADD R7,R9,R7
ADD R7,R6,R7, ROR #+26
// 155 II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */
MVN R9,R5
ORR R9,R9,R7
EOR R9,R9,R6
LDR R10,[SP, #+44]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xF8 ;; 0xffffffffbd3af235
ADD R9,R10,R9
ADD R8,R9,R8
ADD R8,R7,R8, ROR #+22
// 156 II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */
MVN R9,R6
ORR R9,R9,R8
EOR R9,R9,R7
LDR R10,[SP, #+8]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0xFC ;; 0x2ad7d2bb
ADD R9,R10,R9
ADD R5,R9,R5
ADD R5,R8,R5, ROR #+17
// 157 II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */
MVN R9,R7
ORR R9,R9,R5
EOR R9,R9,R8
LDR R10,[SP, #+36]
ADD R9,R10,R9
LDR R10,??ProcessMD5byBlock_0+0x100 ;; 0xffffffffeb86d391
ADD R9,R10,R9
ADD R6,R9,R6
// 158 ctx0+=a;
ADD R0,R7,R0
// 159 ctx1+=b;
ADD R6,R5,R6, ROR #+11
ADD R3,R6,R3
// 160 ctx2+=c;
ADD R12,R5,R12
// 161 ctx3+=d;
ADD R4,R8,R4
// 162 }
// 163 while(--num_of_blocks);
SUBS R2,R2,#+1
BNE ??ProcessMD5byBlock_1
// 164 *dst++=ctx0;
LDR R2,[SP, #+68]
STR R0,[R2], #+4
STR R2,[SP, #+68]
// 165 *dst++=ctx1;
MOV R1,R2
STR R3,[R1], #+4
STR R1,[SP, #+68]
// 166 *dst++=ctx2;
STR R12,[R1], #+4
STR R1,[SP, #+68]
// 167 *dst++=ctx3;
STR R4,[R1, #+0]
// 168 }
ADD SP,SP,#+72 ;; stack cleaning
CFI CFA R13+36
POP {R4-R11,LR}
CFI R4 SameValue
CFI R5 SameValue
CFI R6 SameValue
CFI R7 SameValue
CFI R8 SameValue
CFI R9 SameValue
CFI R10 SameValue
CFI R11 SameValue
CFI ?RET R14
CFI CFA R13+0
BX LR ;; return
DATA
??ProcessMD5byBlock_0:
DC32 0x67452301
DC32 0xffffffffefcdab89
DC32 0xffffffffd76aa478
DC32 0xffffffffe8c7b756
DC32 0x242070db
DC32 0xffffffffc1bdceee
DC32 0xfffffffff57c0faf
DC32 0x4787c62a
DC32 0xffffffffa8304613
DC32 0xfffffffffd469501
DC32 0x698098d8
DC32 0xffffffff8b44f7af
DC32 0xffffffff895cd7be
DC32 0x6b901122
DC32 0xfffffffffd987193
DC32 0xffffffffa679438e
DC32 0x49b40821
DC32 0xfffffffff61e2562
DC32 0xffffffffc040b340
DC32 0x265e5a51
DC32 0xffffffffe9b6c7aa
DC32 0xffffffffd62f105d
DC32 0x2441453
DC32 0xffffffffd8a1e681
DC32 0xffffffffe7d3fbc8
DC32 0x21e1cde6
DC32 0xffffffffc33707d6
DC32 0xfffffffff4d50d87
DC32 0x455a14ed
DC32 0xffffffffa9e3e905
DC32 0xfffffffffcefa3f8
DC32 0x676f02d9
DC32 0xffffffff8d2a4c8a
DC32 0xfffffffffffa3942
DC32 0xffffffff8771f681
DC32 0x6d9d6122
DC32 0xfffffffffde5380c
DC32 0xffffffffa4beea44
DC32 0x4bdecfa9
DC32 0xfffffffff6bb4b60
DC32 0xffffffffbebfbc70
DC32 0x289b7ec6
DC32 0xffffffffeaa127fa
DC32 0xffffffffd4ef3085
DC32 0x4881d05
DC32 0xffffffffd9d4d039
DC32 0xffffffffe6db99e5
DC32 0x1fa27cf8
DC32 0xffffffffc4ac5665
DC32 0xfffffffff4292244
DC32 0x432aff97
DC32 0xffffffffab9423a7
DC32 0xfffffffffc93a039
DC32 0x655b59c3
DC32 0xffffffff8f0ccc92
DC32 0xffffffffffeff47d
DC32 0xffffffff85845dd1
DC32 0x6fa87e4f
DC32 0xfffffffffe2ce6e0
DC32 0xffffffffa3014314
DC32 0x4e0811a1
DC32 0xfffffffff7537e82
DC32 0xffffffffbd3af235
DC32 0x2ad7d2bb
DC32 0xffffffffeb86d391
CFI EndBlock cfiBlock1

RSEG CODE_ID:CODE:NOROOT(2)
`?*?CODE_ID`:

RSEG INITTAB:CODE:ROOT(2)
DATA
?init?tab?CODE_I:
DCD sfe(CODE_I) - sfb(CODE_I), sfb(CODE_I), sfb(CODE_ID)

END
// 169
// 170
//
// 2 772 bytes in segment CODE_I
// 12 bytes in segment INITTAB
//
// 2 768 bytes of CODE memory (+ 16 bytes shared)
//
//Errors: none
//Warnings: none


К сожалению, в IAR'е говно, а не симулятор, посему не могу сказать количества тактов, а считать лень :)

PS Вот это глюк в движке форума - он расставил смайлы внутри codebox...

PPS Да что-же это такое. Еще и ( с ) на значек копирайта заменил...
toweroff
Цитата(Rst7 @ Feb 12 2009, 18:32) *
Вообщем, правильный MD5 для заказанных условий (выровненные круглые блоки) должен выглядеть для ARM7 примерно так


какова должна быть длина в блоках?

длина в байтах / sizeof(unsigned int) * 16 ?

если так, то хэш не совпадает
Rst7
Блок должен быть 64 байта.

Ага, а вот и промашка
Код
unsigned int bitsize=num_of_blocks*8;

надо
Код
unsigned int bitsize=num_of_blocks*8*64;
toweroff
Вот теперь ОК

Выигрыш (по данным Keil) - почти 5,5сек - 22%

Челом в бетон бью smile.gif

Еще бы шашку так оптимизировать... хотя все равно хотел делать как опцию, но очень необходимую smile.gif

Кстати.. поигрался с настройками EMC - циклы ожидания и тд. Никаких изменений -> симулятор не рулит (подождем советов, может что и не включил для полной симуляции)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.