|
Самомодифицирующийся код в экосистеме Cortex-M., есть ли право на жизнь? |
|
|
|
 |
Ответов
|
Jun 29 2018, 06:56
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AlexandrY @ Jun 29 2018, 08:47)  Или самомодифицирующийся - это код который вот именно сам себя модифицирует, т.е. инструкция STR вот прямо по своему адресу что-то и пишет и сама себя таким образом затирает. Я уже выше написал: будет функция, которая по некоторым условиям пишет другую функцию. По командам. В маш.кодах. Команды записываемые в тело создаваемой функции (и их последовательность) зависят от аргументов первой функции. PS: Вот уже сколько откликов получил, а на собственно единственный вопрос, поставленный в первом сообщении, так никто и не ответил. И видимо забыли все в чём был вопрос..... Вопрос был собственно в том: использовал кто-нить из здесь присутствующих самомодифицирующийся код (именно такой код, который или сам своё тело правит или строит другой код (а не просто копирует из одного места в другое))? Именно на платформе ARM в embedded? И, если использовали, то для какой задачи?
|
|
|
|
|
Jun 29 2018, 16:00
|
Местный
  
Группа: Участник
Сообщений: 297
Регистрация: 20-05-17
Пользователь №: 97 202

|
Цитата(AlexandrY @ Jun 29 2018, 10:00)  Тогда я не согласен с названием "самомодифицирующийся", у меня загрузчики тоже загружают разные не то что функции, а целые программы(и да в машинных кодах, разумеется) в зависимости от аргументов. Попытаюсь объяснить (как я это понял), что подразумевать под "самомодифицирующимся кодом" топикстартер. Не. Не буду. Боюсь всё равно не поймёте А разжигать холивар не хочу Впрочем, скажу кое-что. Ваш загрузчик просто подгружает целые законченные куски кода, а у топикстартера программа меняет отдельные команды своего собственного кода
|
|
|
|
|
Jun 29 2018, 17:11
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Николай Семёнович @ Jun 29 2018, 19:00)  Ваш загрузчик просто подгружает целые законченные куски кода, а у топикстартера программа меняет отдельные команды своего собственного кода Вот именно. Даже полностью строит процедуру. Вот такой примерно должен быть результат (код) работы генератора: CODE ;Назначение регистров в динамически генерируемой функции. dstReg EQU c_R0 ;указатель на целевой буфер для записи (вх.аргумент) tblReg EQU c_R1 ;указатель на таблицу адресов переменных (вх.аргумент) tmpReg0 EQU c_R2 ;рабочий регистр 0 tmpReg1 EQU c_R3 ;рабочий регистр 1 ;сама функция ;f0 LDR tmpReg0, [tblReg, #bit1*4]; где bit1 - номер первого единичного бита в мл.слове бит-карты ;f0 LDR tmpReg1, [tblReg, #bit2*4]; где bit2 - номер второго единичного бита в мл.слове бит-карты ;f1 LDR/LDRH tmpReg0, [tmpReg0] ;f2 STR/STRH tmpReg0, [dstReg], #step; где step==4 для STR и step==2 для STRH ;f0 LDR tmpReg0, [tblReg, #bit3*4]; где bit3 - номер 3-го единичного бита в мл.слове бит-карты ;f1 LDR/LDRH tmpReg1, [tmpReg1] ;f2 STR/STRH tmpReg1, [dstReg], #step; где step==4 для STR и step==2 для STRH ;f0 LDR tmpReg1, [tblReg, #bit4*4]; где bit4 - номер 4-го единичного бита в мл.слове бит-карты ;f1 LDR/LDRH tmpReg0, [tmpReg0] ;f2 STR/STRH tmpReg0, [dstReg], #step; где step==4 для STR и step==2 для STRH ; ... ;f3 ADDS tblReg, tblReg, #32*4; вставляется при переходе к ст.слову бит-карты если в нём есть единицы ;f0 LDR tmpReg0, [tblReg, #bit1*4]; где bit1 - номер 1-го единичного бита в ст.слове бит-карты ;f1 LDR/LDRH tmpReg1, [tmpReg1] ;f2 STR/STRH tmpReg1, [dstReg], #step; где step==4 для STR и step==2 для STRH ;f0 LDR tmpReg1, [tblReg, #bit2*4]; где bit2 - номер 2-го единичного бита в ст.слове бит-карты ;f1 LDR/LDRH tmpReg0, [tmpReg0] ;f2 STR/STRH tmpReg0, [dstReg], #step; где step==4 для STR и step==2 для STRH ; ... ;f1 LDR/LDRH tmpReg1, [tmpReg1] ;f2 STR/STRH tmpReg1, [dstReg], #step; где step==4 для STR и step==2 для STRH ;f4 BX LR LDR или LDRH использовать - определяется весом бита, заданным в таблице. Генератор формирует код глядя в эту таблицу. Цитата(Arlleex @ Jun 29 2018, 19:18)  Как видно, в любом случае нет больше в цикле инструкций проверки условий в if(...)-ах (а они же ведь по сути Bxx в ассемблерном представлении) (да и куда лучше вовсе не проверять заранее ложные условия по списку), а выполняются только нужные инструкции сразу, как будто условных конструкций и нет. А п. 1 и 2, конечно, требуют тактов, только для моего случая п. 1. требуется выполнить только 1 раз для всех итераций цикла, на этапе составления списка инструкций СМК. Надеюсь, моя мысль будет так понятнее. Блин, коллега, позвольте пожать Вашу руку! Вы - похоже почти единственный человек на этом форуме сходу понявший все нюансы!!!  Цитата(Arlleex @ Jun 29 2018, 19:56)  Я просто телепат  Как будто заглянули в мои исходники!
|
|
|
|
|
Jun 29 2018, 17:23
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Arlleex @ Jun 29 2018, 20:18)  О результатах сообщите, пожалуйста, удалось/не удалось внедрить, буду держать на всякий случай идею такую. Я довольно плотно поработал с битовой графикой на LCD/TFT дисплеях и организовывал меню разной степени вложенности для пользователей устройств с тачскрином/кнопками и экраном. Там таких ситуаций, где флажки надо опрашивать и определять отрисовки, да на каждом шагу по 50  Ок. Генератор написал, но отлаживать буду завтра - поздно уже. Как заработает - напишу. У меня этот код предназначен для записи текущих значений переменных в поток. Карта выбранных для записи переменных приходит по интерфейсу связи и может меняться в процессе работы иногда, не прерывая процесса. Всего в программе много десятков таких переменных, которые хотелось бы писать, но писать все сразу - не хватит пропускной способности канала. Переменные пока только 16- и 32-битные (целочисленные и float). Каждая битовая позиция в карте закреплена жёстко за какой-то переменной. И есть таблица указателей на эти переменные. И это только - сервисная задача. Её выполнение не должно мешать выполнению основных рабочих задач МК, которых достаточно много и тяжёлых. Но в процессе работы нужно следить за всеми этими переменными. Вот примерно так.
|
|
|
|
|
Jun 29 2018, 21:21
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(jcxz @ Jun 29 2018, 20:23)  Как заработает - напишу. Проверил в железе - работает (Cortex-M0). CODE #include "stdafx.h" #include "conio.h" #include "windows.h"
#define IS_ALIGN (1) #define VAR_NUM (32)
//----------------------------------------------------------------------------- // enum eVAR_TYPE //----------------------------------------------------------------------------- enum eVAR_TYPE { VAR_NONE = 0, VAR_DWORD, VAR_WORD, VAR_BYTE, };
//----------------------------------------------------------------------------- // typedef struct sVAR //----------------------------------------------------------------------------- typedef struct sVAR { union { DWORD data_dw; WORD data_w; BYTE data_b; }; enum eVAR_TYPE type; } sVAR;
volatile sVAR var[VAR_NUM] = { {0x12345678, VAR_DWORD}, {0xABCD, VAR_WORD}, {0x11223344, VAR_DWORD}, {0x55, VAR_BYTE}, {0x00, VAR_BYTE}, {0x66, VAR_BYTE}, {0x77, VAR_BYTE}, {0x88, VAR_BYTE}, {0x99, VAR_BYTE}, {0xAA, VAR_BYTE}, {0xBB, VAR_BYTE}, {0xCC, VAR_BYTE}, {0xDD, VAR_BYTE}, {0xEE, VAR_BYTE}, {0xFF, VAR_BYTE}, {0x98765432, VAR_DWORD}, };
BYTE exec_ram[1024];
//----------------------------------------------------------------------------- // void set_new_mask(const DWORD mask) //----------------------------------------------------------------------------- void set_new_mask(const DWORD mask) { int offset; int last_var = 0; int s_pos = 0; int exec_ram_pos = 0;
printf("// r0 = *s, r1 = var\n");
// PUSH {r2, lr} exec_ram[exec_ram_pos++] = 0x04; exec_ram[exec_ram_pos++] = 0xB5;
printf("B5 04 - push {r2, pc}\n");
for(int i = 0; i < VAR_NUM; i++) { if(mask & (1 << i)) { switch(var[i].type) { case VAR_DWORD: printf("// DWORD[%d]\n", i);
offset = (i - last_var) * 8; last_var = i;
while(offset > 128) { offset -= 128; // ADD r1, #128 exec_ram[exec_ram_pos++] = 128; exec_ram[exec_ram_pos++] = 0x31;
printf("31 80 - add r1, #128\n"); }
if(offset) { // ADD r1, #offset exec_ram[exec_ram_pos++] = offset; exec_ram[exec_ram_pos++] = 0x31;
printf("31 %02X - add r1, #%d\n", offset, offset); }
if(IS_ALIGN && (s_pos & 1)) { // byte align
// LDRB r2, [r1, #0] exec_ram[exec_ram_pos++] = 0x0A; exec_ram[exec_ram_pos++] = 0x78;
printf("78 0A - ldrb r2, [r1, #0]\n");
// STRB r2, [r0, #0] exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x70;
printf("70 02 - strb r2, [r0, #0]\n");
// LDRB r2, [r1, #1] exec_ram[exec_ram_pos++] = 0x4A; exec_ram[exec_ram_pos++] = 0x78;
printf("78 4A - ldrb r2, [r1, #1]\n");
// STRB r2, [r0, #1] exec_ram[exec_ram_pos++] = 0x42; exec_ram[exec_ram_pos++] = 0x70;
printf("70 42 - strb r2, [r0, #1]\n");
// LDRB r2, [r1, #2] exec_ram[exec_ram_pos++] = 0x8A; exec_ram[exec_ram_pos++] = 0x78;
printf("78 8A - ldrb r2, [r1, #2]\n");
// STRB r2, [r0, #2] exec_ram[exec_ram_pos++] = 0x82; exec_ram[exec_ram_pos++] = 0x70;
printf("70 82 - strb r2, [r0, #2]\n");
// LDRB r2, [r1, #3] exec_ram[exec_ram_pos++] = 0xCA; exec_ram[exec_ram_pos++] = 0x78;
printf("78 CA - ldrb r2, [r1, #3]\n");
// STRB r2, [r0, #3] exec_ram[exec_ram_pos++] = 0xC2; exec_ram[exec_ram_pos++] = 0x70;
printf("70 C2 - strb r2, [r0, #3]\n"); } else if(IS_ALIGN && (s_pos & 2)) { // word align
// LDRH r2, [r1, #0] exec_ram[exec_ram_pos++] = 0x0A; exec_ram[exec_ram_pos++] = 0x88;
printf("88 0A - ldrh r2, [r1, #0]\n");
// STRH r2, [r0, #0] exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x80;
printf("80 02 - strh r2, [r0, #0]\n");
// LDRH r2, [r1, #2] exec_ram[exec_ram_pos++] = 0x4A; exec_ram[exec_ram_pos++] = 0x88;
printf("88 4A - ldrh r2, [r1, #2]\n");
// STRH r2, [r0, #2] exec_ram[exec_ram_pos++] = 0x42; exec_ram[exec_ram_pos++] = 0x80;
printf("80 42 - strh r2, [r0, #2]\n"); } else { // dword align
// LDR r2, [r1, #0] exec_ram[exec_ram_pos++] = 0x0A; exec_ram[exec_ram_pos++] = 0x68;
printf("68 0A - ldr r2, [r1, #0]\n");
// STR r2, [r0, #0] exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x60;
printf("60 02 - str r2, [r0, #0]\n"); }
// ADDS r0, #4 exec_ram[exec_ram_pos++] = 0x04; exec_ram[exec_ram_pos++] = 0x30;
printf("30 04 - adds r0, #4\n");
s_pos += 4; break;
case VAR_WORD: printf("// WORD[%d]\n", i);
offset = (i - last_var) * 8; last_var = i;
while(offset > 128) { offset -= 128; // ADD r1, #128 exec_ram[exec_ram_pos++] = 128; exec_ram[exec_ram_pos++] = 0x31;
printf("31 80 - add r1, #128\n"); }
if(offset) { // ADD r1, #offset exec_ram[exec_ram_pos++] = offset; exec_ram[exec_ram_pos++] = 0x31;
printf("31 %02X - add r1, #%d\n", offset, offset); }
if(IS_ALIGN && (s_pos & 1)) { // byte align
// LDRB r2, [r1, #0] exec_ram[exec_ram_pos++] = 0x0A; exec_ram[exec_ram_pos++] = 0x78;
printf("78 0A - ldrb r2, [r1, #0]\n");
// STRB r2, [r0, #0] exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x70;
printf("70 02 - strb r2, [r0, #0]\n");
// LDRB r2, [r1, #1] exec_ram[exec_ram_pos++] = 0x4A; exec_ram[exec_ram_pos++] = 0x78;
printf("78 4A - ldrb r2, [r1, #1]\n");
// STRB r2, [r0, #1] exec_ram[exec_ram_pos++] = 0x42; exec_ram[exec_ram_pos++] = 0x70;
printf("70 42 - strb r2, [r0, #1]\n"); } else { // word align
// LDRH r2, [r1, #0] exec_ram[exec_ram_pos++] = 0x0A; exec_ram[exec_ram_pos++] = 0x88;
printf("88 0A - ldrh r2, [r1, #0]\n");
// STRH r2, [r0, #0] exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x80;
printf("80 02 - strh r2, [r0, #0]\n"); }
// ADDS r0, #2 exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x30;
printf("30 02 - adds r0, #2\n");
s_pos += 2; break;
case VAR_BYTE: printf("// BYTE[%d]\n", i);
offset = (i - last_var) * 8; last_var = i;
while(offset > 128) { offset -= 128; // ADD r1, #128 exec_ram[exec_ram_pos++] = 128; exec_ram[exec_ram_pos++] = 0x31;
printf("31 80 - add r1, #128\n\r"); }
if(offset) { // ADD r1, #offset exec_ram[exec_ram_pos++] = offset; exec_ram[exec_ram_pos++] = 0x31;
printf("31 %02X - add r1, #%d\n", offset, offset); }
// LDRB r2, [r1, #0] exec_ram[exec_ram_pos++] = 0x0A; exec_ram[exec_ram_pos++] = 0x78;
printf("78 0A - ldrb r2, [r1, #0]\n");
// STRB r2, [r0, #0] exec_ram[exec_ram_pos++] = 0x02; exec_ram[exec_ram_pos++] = 0x70;
printf("70 02 - strb r2, [r0, #0]\n");
// ADDS r0, #1 exec_ram[exec_ram_pos++] = 0x01; exec_ram[exec_ram_pos++] = 0x30;
printf("30 01 - adds r0, #1\n");
s_pos += 1; break; } } } printf("// EXIT\n");
// POP {r2, pc} exec_ram[exec_ram_pos++] = 0x04; exec_ram[exec_ram_pos++] = 0xBD;
printf("BD 04 - pop {r2, pc}\n");
#if 0 printf("SMC:\n"); for(int i = 0; i < exec_ram_pos / 2; i++) printf("%02X %02X\n", exec_ram[i * 2 + 1], exec_ram[i * 2 + 0]); #endif }
int _tmain(int argc, _TCHAR* argv[]) { set_new_mask(0xc7); _getch(); return 0; }
СМК: CODE // r0 = *s, r1 = var B5 04 - push {r2, pc} // DWORD[0] 68 0A - ldr r2, [r1, #0] 60 02 - str r2, [r0, #0] 30 04 - adds r0, #4 // WORD[1] 31 08 - add r1, #8 88 0A - ldrh r2, [r1, #0] 80 02 - strh r2, [r0, #0] 30 02 - adds r0, #2 // DWORD[2] 31 08 - add r1, #8 88 0A - ldrh r2, [r1, #0] 80 02 - strh r2, [r0, #0] 88 4A - ldrh r2, [r1, #2] 80 42 - strh r2, [r0, #2] 30 04 - adds r0, #4 // BYTE[6] 31 20 - add r1, #32 78 0A - ldrb r2, [r1, #0] 70 02 - strb r2, [r0, #0] 30 01 - adds r0, #1 // BYTE[7] 31 08 - add r1, #8 78 0A - ldrb r2, [r1, #0] 70 02 - strb r2, [r0, #0] 30 01 - adds r0, #1 // EXIT BD 04 - pop {r2, pc} Результат на Cortex-M0 Цитата RESULT[20000F44]: 78 56 34 12 CD AB 44 33 22 11 77 88
|
|
|
|
|
Jun 30 2018, 00:22
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(adnega @ Jun 30 2018, 00:21)  Проверил в железе - работает (Cortex-M0). мммм... неправильно См. моё сообщение #39 - какой должен быть результат работы. К тому же: a) const в аргументе set_new_mask() - лишнее; б) R2,LR в вашей функции - не нужно сохранять, см. соглашения вызова компилятора; в) даже по Вашему алгоритму копирования - очень неоптимально, количество команд в 2 раза больше, чем можно было бы (для Cortex-M4).
|
|
|
|
|
Jun 30 2018, 06:41
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(jcxz @ Jun 30 2018, 03:22)  мммм... неправильно А что именно неправильно? Есть таблица переменных состоящая из значений и типов. Есть маска, где каждый бит связан с соответствующим элементом таблицы. Есть функция-генератор, создающая в рантайме код, при выполнении которого в выходной поток копируются данные из таблицы с учетом длины и заданной маски. Для заданного var, RESULT (отработал СМК) такой ожидаете? Если нет, то где ошибка? Цитата(jcxz @ Jun 30 2018, 03:22)  a) const в аргументе set_new_mask() - лишнее; Ну, функция set_new_mask не должна менять mask, поэтому и const. Или я вас не понял. Цитата(jcxz @ Jun 30 2018, 03:22)  б) R2,LR в вашей функции - не нужно сохранять, см. соглашения вызова компилятора; Вы же супер-скорость хотели. Выкидывайте push и pop - и вот вам готовый участок кода, дающий результат, но не забудьте проинициализировать r0 и r1. Если нужна именно как функция, то достаточно одного "bx lr" в конце. Цитата(jcxz @ Jun 30 2018, 03:22)  в) даже по Вашему алгоритму копирования - очень неоптимально, количество команд в 2 раза больше, чем можно было бы (для Cortex-M4). Какие именно команды лишние? Можно IS_ALIGN обнулить, тогда генератор будет работать с невыровненными данными. Попробую сегодня избавиться от лишних adds.
|
|
|
|
|
Jun 30 2018, 07:21
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(adnega @ Jun 30 2018, 09:41)  А что именно неправильно? Есть таблица переменных состоящая из значений и типов. Вы же ассемблер понимаете? Тогда посмотрите на требуемый результат (код) в сообщении #39 и поймёте в чём разница. Нет таблицы переменных, есть таблица указателей на переменные. Так как эти переменные разбросаны по всей программе и объединить их в одну область памяти (структуру) нельзя. Они находятся в разных обособленных службах программы, и там и должны оставаться. А адресация их идёт через таблицу указателей. Я писал об этом. И в примере результата это чётко видно. Если си-исходник будет понятней, то: CODE enum {N = <максимум 64>}; enum {TYP_s16, TYP_u16, TYP_s32, TYP_u32, TYP_float, TYP_n}; struct { u8 main:3; u8 misc:5; } const isTyp[N] = {{TYP_s32, ...}, {TYP_u16, ...}, ...}; u8 isTypSize[TYP_n] = {2, 2, 4, 4, 4}; char *psrc; char *pdst; if (map & 1 << 0) { psrc = varPtrs[0]; if (isTypSize[isTyp[0].main]) == 4) { *(u32 *)pdst = *(u32 *)psrc; pdst += 4; } else { *(u16 *)pdst = *(u16 *)psrc; pdst += 2; } } if (map & 1 << 1) { psrc = varPtrs[1]; if (isTypSize[isTyp[1].main]) == 4) { *(u32 *)pdst = *(u32 *)psrc; pdst += 4; } else { *(u16 *)pdst = *(u16 *)psrc; pdst += 2; } } //и так далее... так сейчас в си-исходнике сделано. Цель СМК - построить оптимальный код выкинув кучу ненужных операций из этого алгоритма по текущей карте map, до следующего её изменения. Цитата(adnega @ Jun 30 2018, 09:41)  Какие именно команды лишние? Можно IS_ALIGN обнулить, тогда генератор будет работать с невыровненными данными. Попробую сегодня избавиться от лишних adds. У меня Cortex-M4. Он поддерживает команды с пост- и пре- модификациями адреса. Например: LDR R0, [R1], #4 тогда ваш код сократится в 2 раза. Да я уже вчера всё сделал. И даже больше. Мой генератор ещё и перемежение команд поддерживает для исключения штрафов между командами LDR.  И я его на асме написал. Хотя это просто из спортивного интереса.
|
|
|
|
|
Jun 30 2018, 08:59
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(jcxz @ Jun 30 2018, 10:21)  Да я уже вчера всё сделал Покажите пожалуйста выход генератора для случая DWORD, WORD, DWORD, BYTE, BYTE в виде asm-инструкций. У меня с таблицей переменных и невыровненными данным получилось так CODE // r0 = *s, r1 = var // DWORD[0] 68 0A - ldr r2, [r1, #0] 60 02 - str r2, [r0, #0] // WORD[1] 89 0A - ldrh r2, [r1, #8] 80 82 - strh r2, [r0, #4] // DWORD[2] 8A 0A - ldrh r2, [r1, #16] 80 C2 - strh r2, [r0, #6] 8A 4A - ldrh r2, [r1, #18] 81 02 - strh r2, [r0, #8] // BYTE[6] 31 30 - add r1, #48 78 0A - ldrb r2, [r1, #0] 72 82 - strb r2, [r0, #10] // BYTE[7] 7A 0A - ldrb r2, [r1, #8] 72 C2 - strb r2, [r0, #11] 30 0C - adds r0, #12 47 70 - bx lr
Кста, а есть у кого-нить справочник машинных кодов для Cortex-M всех семейств? Не путать со справочником asm-команд, который найти не составляет труда.
|
|
|
|
|
Jun 30 2018, 11:56
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(adnega @ Jun 30 2018, 11:59)  Покажите пожалуйста выход генератора для случая DWORD, WORD, DWORD, BYTE, BYTE в виде asm-инструкций. Да, как только поборю IAR. Если у Вас IAR, то как Вы ему сказали, чтобы он массив объявленный в программе как массив, показывал в окне дизасма как код? А то у меня он, собака, как только видит что это массив, показывает просто как кучу констант DC32 как этот массив не объявляй. Не могу заставить его дизассемблировать  ((( И мне не нужны байтовые операции - переменные только 16 и 32 бита. Цитата(adnega @ Jun 30 2018, 11:59)  Кста, а есть у кого-нить справочник машинных кодов для Cortex-M всех семейств? Мне тоже хотелось-бы. Не нашёл в инете. Только если правильно выражаться: таблица маш.кодов набора инструкций Thumb-2. Цитата(AlexandrY @ Jun 30 2018, 13:09)  Господа, вы тут явно пытаетесь эмулировать DMA.  Да причём тут DMA??? Каким боком он поможет в этой задаче? Разве чтобы только затормозить процедуру в несколько раз? Цитата(AVI-crak @ Jun 30 2018, 14:24)  Более простое название этого процесса - полиморфный код. Мне без разницы как это называть. Пускай будет полиморфный. А что именно требуется - мне кажется уже каждый должен был понять, хоть немного почитав тред.
|
|
|
|
|
Jun 30 2018, 13:30
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(adnega @ Jun 30 2018, 15:12)  Можете скинуть бинарь - я его конвертну, если у вас нет gcc. Спасибо, уже не надо - просто копировал из массива результат в неиспользуемую память МК, а для такой памяти IAR позволяет делать дизасм. Так и отладил. Вобщем: всё ок работает алгоритм. Ниже прикладываю результат его работы для 64-битного слова: 0000.002A.1003.0006. При таких весах битов карты (см. установленные биты в бит-карте выше): бит1=2 байта, бит2=2 байта, бит16=4 байта, бит17=2 байта, бит28=4 байта, бит33=4 байта, бит35=4 байта, бит37=2 байта. Результат картинкой (не знаю как в IAR сохранить текстовое содержимое окна дизасма, а InqSoft Scaner не захватывает текст из этого окна):
А здесь результат в бинарнике:
smk00.zip ( 233 байт )
Кол-во скачиваний: 4Итого - время выполнения этого кода думаю будет == примерно 31 такт (не измерял), при условии что dst на входе - выровнен на 4. Как можно догадаться: функция строится таким образом, чтобы она была определена как: extern "C" void * Func(void *dst, u32 *table);где: dst - буфер для записи (передаётся в R0); table - массив из 64-х указателей на захватываемые переменные. Цитата(AlexandrY @ Jun 30 2018, 16:17)  Скопирует все переменные в одну область и вышлет куда надо. Или даже без копирования вышлет. Ну-ну. А теперь объясните как он это скопирует, когда переменные разбросаны по всей памяти МК кусочками по 2 и по 4 байта?  Про передачу свЯзными списками я в курсе.
|
|
|
|
Сообщений в этой теме
jcxz Самомодифицирующийся код в экосистеме Cortex-M. Jun 28 2018, 22:54 aaarrr Цитата(jcxz @ Jun 29 2018, 01:54) И вот я... Jun 28 2018, 23:01 AVI-crak Цитата(jcxz @ Jun 29 2018, 04:54) Просто ... Jun 28 2018, 23:23 aaarrr Цитата(AVI-crak @ Jun 29 2018, 02:23... Jun 28 2018, 23:31  AVI-crak Не предполагает.
Любая перетасовка программного ко... Jun 29 2018, 00:11 Николай Семёнович Цитата(AVI-crak @ Jun 29 2018, 02:23... Jun 29 2018, 03:22 jcxz Цитата(AVI-crak @ Jun 29 2018, 02:23... Jun 29 2018, 04:20 aaarrr Давайте сначала:
Цитата(AVI-crak @ Jun ... Jun 29 2018, 00:32 AVI-crak Цитата(aaarrr @ Jun 29 2018, 06:32) О как... Jun 29 2018, 04:47  jcxz Цитата(AVI-crak @ Jun 29 2018, 07:36... Jun 29 2018, 04:51   AVI-crak Цитата(jcxz @ Jun 29 2018, 10:51) Вы о чё... Jul 1 2018, 15:22    VladislavS Цитата(AVI-crak @ Jul 1 2018, 18:22)... Jul 1 2018, 16:25     jcxz Цитата(VladislavS @ Jul 1 2018, 19:25) Пр... Jul 2 2018, 16:12      AVI-crak Цитата(jcxz @ Jul 2 2018, 22:12) Конечно ... Jul 2 2018, 20:46       Arlleex Цитата(AVI-crak @ Jul 3 2018, 00:46)... Jul 3 2018, 04:44        AVI-crak Цитата(Arlleex @ Jul 3 2018, 10:44) А отк... Jul 3 2018, 18:38  aaarrr Цитата(AVI-crak @ Jun 29 2018, 07:47... Jun 29 2018, 07:24 halfdoom Цитата(jcxz @ Jun 29 2018, 01:54) Есть мы... Jun 29 2018, 03:29   jcxz Цитата(AlexandrY @ Jun 29 2018, 10:00) То... Jun 29 2018, 07:03    AlexandrY Цитата(jcxz @ Jun 29 2018, 10:03) Ну хоро... Jun 29 2018, 07:05       Arlleex Цитата(jcxz @ Jun 29 2018, 20:23) Всего в... Jun 29 2018, 17:36            AlexandrY Цитата(adnega @ Jun 30 2018, 11:59) Кста,... Jun 30 2018, 10:09                jcxz Цитата(AlexandrY @ Jun 30 2018, 16:39) И ... Jun 30 2018, 13:56                 AlexandrY Цитата(jcxz @ Jun 30 2018, 16:56) В то вр... Jun 30 2018, 14:43                  jcxz Цитата(AlexandrY @ Jun 30 2018, 17:43) Та... Jun 30 2018, 19:41                   AlexandrY Цитата(jcxz @ Jun 30 2018, 22:41) Ваш пос... Jul 1 2018, 07:22             AlexandrY Цитата(jcxz @ Jun 30 2018, 14:56) Да прич... Jun 30 2018, 13:17 Serge V Iz Использовал хранимые в ОЗУ участки кода, которые з... Jun 29 2018, 07:35 jcxz Цитата(Serge V Iz @ Jun 29 2018, 10:35) И... Jun 29 2018, 08:43 AVR Цитата(jcxz @ Jun 29 2018, 01:54) Есть мы... Jun 29 2018, 07:43 a123-flex Цитата(AVR @ Jun 29 2018, 10:43) Оптимиза... Jun 29 2018, 15:05 RadiatoR Вопрос к ТС - а каков предполагаемый размер генери... Jun 29 2018, 07:54 _4afc_ Мой опыт показывает что оптимизация по скорости са... Jun 29 2018, 08:23 jcxz Цитата(RadiatoR @ Jun 29 2018, 10:54) Во... Jun 29 2018, 09:08  _4afc_ Цитата(jcxz @ Jun 29 2018, 13:08) А тепер... Jun 29 2018, 09:53 VladislavS _4afc_, не стоит быть столь категоричным. Если гов... Jun 29 2018, 08:38 Kabdim Имхо сейчас время такое что проще взять более мощн... Jun 29 2018, 08:44 Arlleex Интересная тема для меня, тема СМК. Ни разу не при... Jun 29 2018, 13:08 RadiatoR Цитата(Arlleex @ Jun 29 2018, 16:08) 2. Н... Jun 29 2018, 13:23 adnega Цитата(Arlleex @ Jun 29 2018, 16:08) 1. П... Jun 29 2018, 16:03  Arlleex Цитата(RadiatoR @ Jun 29 2018, 16:23) Та... Jun 29 2018, 16:18   adnega Цитата(Arlleex @ Jun 29 2018, 19:18) Наде... Jun 29 2018, 16:35    Arlleex Цитата(adnega @ Jun 29 2018, 19:35) Услов... Jun 29 2018, 16:56 jcxz Цитата(Arlleex @ Jun 29 2018, 16:08) Прив... Jun 29 2018, 16:56  AlexandrY Цитата(jcxz @ Jun 29 2018, 19:56) ...
if ... Jun 29 2018, 17:44 kolobok0 Цитата(Arlleex @ Jun 29 2018, 16:08) Инте... Jun 29 2018, 17:46 a123-flex Цитата(jcxz @ Jun 29 2018, 01:54) Есть мы... Jun 29 2018, 13:27 twix Цитата(a123-flex @ Jun 29 2018, 14:2... Jun 29 2018, 14:35 Serge V Iz Кстати, а какие есть основания предполагать, что р... Jun 29 2018, 16:11 Arlleex Цитата(AlexandrY @ Jun 29 2018, 20:44) А ... Jun 29 2018, 18:19 AVI-crak Цитата(jcxz @ Jun 29 2018, 04:54) Есть мы... Jun 30 2018, 11:24 Arlleex jcxz, а зачем тут это? Вы сначала загружаете адрес... Jun 30 2018, 15:09 jcxz Цитата(Arlleex @ Jun 30 2018, 18:09) А вы... Jun 30 2018, 19:31  VladislavS Цитата(jcxz @ Jun 30 2018, 22:31) Здесь н... Jun 30 2018, 19:35  Arlleex Цитата(jcxz @ Jun 30 2018, 23:31) Поэтому... Jun 30 2018, 19:45   jcxz Цитата(Arlleex @ Jun 30 2018, 22:45) По т... Jun 30 2018, 19:54 VladislavS Недавно в другой теме проскакивал вот такой код. П... Jun 30 2018, 18:33 Arlleex Кстати, решил почитать внимательнее 3.3.2. Load/st... Jul 1 2018, 10:03 jcxz Цитата(Arlleex @ Jul 1 2018, 13:03) Что э... Jul 1 2018, 12:00
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|