Цитата(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