Сейчас на форуме: rmn, Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+5 невидимых)

 eXeL@B —› Программирование —› Интерпретатор asm
<< . 1 . 2 .
Посл.ответ Сообщение

Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 13 апреля 2008 15:25
· Личное сообщение · #1

Пишу интерпретатор асма на BCB6, с бнф, лексическим, синтакс. и семант. анализом.
И вот встал вопрос - как реализовать сами команды =)
К примеру под регистры я выделю WORD reg_ax;
Но как обратится к al, ah? Помню сдвиг должен быть в Си как shr \ shl, но конкретно не знаю =(
Теперь ещё веселее - интерпретация к примеру mov [ax+2], dx
Вертится в голове, что можно сделать универсальную функция func_mov и передать ей 2 указателя что ли, но конкретику уловить не могу. Скобки [] - всегда разадресация указателя?
Переменные реализ. как структура String name; char *nnn для строк с инитом через new, для обычных word \ byte соотв структуры. Вообщем, нужен светлый взгляд со стороны, поделитесь идеями =)




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 16 апреля 2008 07:42 · Поправил: s0larian
· Личное сообщение · #2


dword read_dword(dword address)
{
dword *p = (dword*)address;
return *p;
}
void write_dword(dword address, dword value)
{
dword *p = (dword*)address;
*p = value;
}


P.S. начинай читать книгу по С, ну или, на худой конец, форум по С.




Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 16 апреля 2008 09:33
· Личное сообщение · #3

Rascal
не нравятся длинные записи можно укоротить через теже дефайны
было:
REG eax;

eax.__reg32 = 0x12345678;
WORD ax = eax.__reg16.W; // 0x5678
BYTE ah = eax.__reg8.BH; // 0x56
BYTE al = eax.__reg8.BL; // 0x78

стало:

#define r32(x) ((x).__reg32)
#define r16(x) ((x).__reg16.W)
#define r8l(x) ((x).__reg8.BL)
#define r8h(x) ((x).__reg8.BH)

REG eax;

r32(eax) = 0x12345678;
WORD ax = r16(eax); // 0x5678
BYTE ah = r8h(eax); // 0x56
BYTE al = r8l(eax); // 0x78

относительно последнего, то
DWORD *d; // указатель на дворд
*d = 0x12345678; // разыменовывание указателя

-----
127.0.0.1, sweet 127.0.0.1





Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 16 апреля 2008 11:23 · Поправил: OKOB
· Личное сообщение · #4

что касается ядра интепретатора ниже всех "с бнф, лексическим, синтакс. и семант. анализом", то оно такое же как в эмулирующем отладчике или любой виртуальной машине (исполнительной кросплатформенной или прота). Отличие только в декодировании команды (эмулирующий отладчик или кросплатформенная ВМ - дизассемблер, виртуальная машина прота - в зависимости от оного) и извлечении
параметров команды.

например кусочек исполнительной части виртуальной машины фимки (risc64) выглядит вот так
push esi
mov eax, [edi+SL_VM_Context.Flag]
and eax, 8 ; stack
shr eax, 3
or al, al
jz short loc_579D71
lea esi, [esp+10h]
mov eax, [edi+SL_VM_Context.Flag]
and eax, 6 ; size operand
shr eax, 1

loc_579D08:
mov bl, 1
or al, al
jnz short loc_579D26
mov eax, [esi]
mov ecx, [esi-4]
push [edi+SL_VM_Context._FLAGS]
popf
add al, cl
pushf
pop [edi+SL_VM_Context._FLAGS]
or bl, bl
jnz short loc_579D62
mov [esi], al
inc esi
jmp short loc_579D62
loc_579D26:
cmp al, 1
jnz short loc_579D46
mov eax, [esi]
mov ecx, [esi-4]
push [edi+SL_VM_Context._FLAGS]
popf
loc_579D33:
add ax, cx
pushf
pop [edi+SL_VM_Context._FLAGS]
or bl, bl
jnz short loc_579D62
mov [esi], ax
add esi, 2
jmp short loc_579D62
loc_579D46:
cmp al, 2
jnz short loc_579D62
mov eax, [esi]
mov ecx, [esi-4]
push [edi+SL_VM_Context._FLAGS]
popf
loc_579D53:
add eax, ecx
pushf
pop [edi+SL_VM_Context._FLAGS]
or bl, bl
jnz short loc_579D62
mov [esi], eax
add esi, 4
loc_579D62:
pop esi
or bl, bl
jnz short loc_579D6C
add esp, 4
jmp short loc_579D8E
loc_579D6C:
add esp, 8
jmp short loc_579D8E
loc_579D71:
mov eax, [edi+SL_VM_Context.Flag]
and eax, 1
shr eax, 0
or al, al
jz short loc_579D8D
mov ecx, [esp+8]
mov eax, [esp+4]
mov eax, [eax]
loc_579D88:
add eax, ecx
mov [edi+SL_VM_Context.Register], eax
loc_579D8D:
pop esi

ИМХО без ассемблерных вставок или вынесения ядра в чистый асм не обойтись

посмотри плагины к ИДА в сырках
--> IDA-x86emu <-- http://ida-x86emu.sourceforge.net/
--> x86_emulator_plugin by dragon <-- http://www.openrce.org/downloads/details/23/x86_emulator_plugin

-----
127.0.0.1, sweet 127.0.0.1




Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 17 апреля 2008 13:12
· Личное сообщение · #5

Сэмулировал половину команд, обработал данные, пока обхожусь без асемблера.
Вообщем 50% работ - полёт нормальный. Кода только многовато будет.
Выделил операторы с 2, 1 и без операндов.
Соотв. потом функциям - эмуляторам передаю указатели на данные и размер вопроса (b,w,dw) + ещё одна переменная для закидонов типа помещения указателя.




Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 17 апреля 2008 13:20
· Личное сообщение · #6

ассемблерные вставки нужны для правильного учета результирующих флагов
(из структуры -> в реальные флаги; выполнение операции; из флагов -> в структуру
push [edi+SL_VM_Context._FLAGS]
popf
add eax, ecx
pushf
pop [edi+SL_VM_Context._FLAGS]

-----
127.0.0.1, sweet 127.0.0.1





Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 17 апреля 2008 18:23 · Поправил: Rascal
· Личное сообщение · #7

для каждой команды, которая может изменить состояние флагов - жестоко. да и это уже эмуль. для основных битов можно и самому сделать учет - типа нуля, переполнения, больше, знака и паритета.

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 18 апреля 2008 02:56
· Личное сообщение · #8

а я так и делаю. эмулирую-то команду я сам, вот в ней и изменяю флаги-структуру.



Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 18 апреля 2008 09:32
· Личное сообщение · #9

что-то не пойму.
struct dup_data {
AnsiString name;
char *data;
int len;
};
// нужно вывести все символы из data (ему выделяю память через new), ну или символов 30, не принципиально
wsprintf(tmp,"Len: %d Hex: 0x%-020X",perem_dup[n].len, *perem_dup[n].data); // выводит один символ из строки и всё =(



Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 18 апреля 2008 10:17 · Поправил: cppasm
· Личное сообщение · #10

А в data что? Если строки, то так:
wsprintf(tmp,"Len: %d Hex: %s",perem_dup[n].len, perem_dup[n].data);
А если именно массив чисел то надо где-то так делать:

wsprintf(tmp,"Len: %d Hex:",perem_dup[n].len);
for(i=0;i<num_elements;i++)
wsprintf(tmp+strlen(tmp)," 0x%-08X",*(perem_dup[n].data+i));


А вообще если не секрет для чего эмулятор делается?
Я просто писал эмулятор SSE для работы программ с SSE на процессорах без него.
Скорость оставляет желать лучшего... Т.е. всё работает, но очень медленно.



Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 18 апреля 2008 12:36
· Личное сообщение · #11

Эмулятор делается для "глубокого изучения теории языков программирования и ознакомления с теоритической и практической основой работы компиляторов" =[



Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 18 апреля 2008 13:47
· Личное сообщение · #12

Ясно всё Ну так ты бы ознакомился с языком программирования прежде чем эмулятор писать...




Ранг: 527.7 (!), 381thx
Активность: 0.160.09
Статус: Участник
Победитель турнира 2010

Создано: 18 апреля 2008 15:14
· Личное сообщение · #13

если так, то лучше бы почитал --> "книгу дракона" <-- http://www.williamspublishing.com/Books/978-5-8459-1349-4.html , предыдущее издание --> ebook <-- http://masterpc.alfaspace.net/books/CCScience/AhoSetiUlman_Kompilyators-www.masterpc.alfaspace.net.djvu

-----
127.0.0.1, sweet 127.0.0.1




Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 18 апреля 2008 18:40
· Личное сообщение · #14

Книжку с драконом читал, там про интерпретаторы ничего практически нет, но теория, лекический и синтаксический анализ - оттуда.



Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 18 апреля 2008 18:43
· Личное сообщение · #15

> Ясно всё Ну так ты бы ознакомился с языком программирования прежде чем эмулятор писать...
Ноно! Я не откровенный ламак, просто вместо лекций по ТЯВУ я кодил в асме и ковырял шаровары =) Так что встречаются пробелы.




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 18 апреля 2008 20:17
· Личное сообщение · #16

Freecod пишет:
wsprintf(tmp,"Len: %d Hex: 0x%-020X",perem_dup[n].len, *perem_dup[n].data);

У тебя прога компилится в Unicode? Указатель у тебя "char *", т.ч. вызывай sprintf()




Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 18 апреля 2008 20:31
· Личное сообщение · #17

да строка ваще мясная. разыменовывание указателя на строку. т.е. он хочет получить первый символ. честно говоря я не понимаю что подразумевается под конструкцией 0x%-020X. видимо нечто типа 0x%02X. хз что за "-".

Freecod пишет:
просто вместо лекций по ТЯВУ я кодил в асме и ковырял шаровары =) Так что встречаются пробелы.

хм. ну видимо не стоило так распределять усилия неравномерно. си судя по твоим постам на ооочень низком уровне. даж не то что си, а понимание логических операций, различия между unicode и ascii, да и разыменовывания не знать в си - это сильно. это я даж не знаю скоко минут ты изучал си за все время. учи матчасть кароч.

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 19 апреля 2008 11:49 · Поправил: Freecod
· Личное сообщение · #18

Конструкция 0x%-020X согласно MSDN должна вывести "0x[20 символов в формате hex, дополненный нулями справа]". Разименовывание идёт как раз правильное, в противном случае будет выведен само значение указателя =\ Кто говорил о юникоде? Стандартный один байт на данные. Аналог shr shl я мог найти в книжке, но она дома, а форум рядом. Вообщем, не делайте меня беднее, чем я есть ='(

Разименовываю я указатель для того что бы получить строку, но он упорно не хочет выводить вольше 1 байта если там 0. То есть если там 12345678h - он это выведет. но если записать больше DWORD - выводит только первый DWORD, а мне нужно получить полноценную строку заданной длинны в hex, со _всеми_ данными, с нулями в том числе.
Метод cppasm пока не пробовал, но думаю это подойдёт.




Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 19 апреля 2008 13:23
· Личное сообщение · #19

длинные hex строки выводил так

for(int i = 0; i < CRYPT_KEY_LENGHT; i++){
sprintf (buffer + i*2,"%02X", crypt_key[i]);
}

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 108.7 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 19 апреля 2008 19:14
· Личное сообщение · #20

Кстати, вопрос не по теме - приоритет консольного приложения, запущенного из *.bat можно задать?



Ранг: 352.4 (мудрец), 4thx
Активность: 0.150
Статус: Участник
retired

Создано: 19 апреля 2008 19:22
· Личное сообщение · #21

Freecod пишет:
приоритет консольного приложения, запущенного из *.bat можно задать?


start /?


<< . 1 . 2 .
 eXeL@B —› Программирование —› Интерпретатор asm
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати