Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Hishnik писал(а): А засорение словаря не будет ли еще меньше, чем размер буфера, выделенный "на всякий случай"? оно будет(засорение). Но тут важно как кользоваться инструментом. Лично мне удобно, а в ряде случаев необходимо (остальное лирика). Потом, надо отдавать себе отчет, что я делал экспериментальную систему, в которой опробовал множество различных решений (возможно иногда спорных), которые можно потрогать руками, а не строить замки в уме. Hishnik писал(а): с потенциальными побочными эффектами. форт, так уж вышло, состоит из побочных эффектов.
[quote="Hishnik"]А засорение словаря не будет ли еще меньше, чем размер буфера, выделенный "на всякий случай"?[/quote] оно будет(засорение). Но тут важно как кользоваться инструментом. Лично мне удобно, а в ряде случаев необходимо (остальное лирика). Потом, надо отдавать себе отчет, что я делал экспериментальную систему, в которой опробовал множество различных решений (возможно иногда спорных), которые можно потрогать руками, а не строить замки в уме. [quote="Hishnik"]с потенциальными побочными эффектами.[/quote] форт, так уж вышло, состоит из побочных эффектов.
|
|
|
|
Добавлено: Сб июл 11, 2015 05:36 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
mOleg писал(а): чтобы его не засорять. А засорение словаря не будет ли еще меньше, чем размер буфера, выделенный "на всякий случай"? Какое-то навязанное решение получается, с еще одной константой, с потенциальными побочными эффектами.
[quote="mOleg"]чтобы его не засорять.[/quote] А засорение словаря не будет ли еще меньше, чем размер буфера, выделенный "на всякий случай"? Какое-то навязанное решение получается, с еще одной константой, с потенциальными побочными эффектами.
|
|
|
|
Добавлено: Пт июл 10, 2015 23:40 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
mgw писал(а): Почему для этого не использовать словарь? чтобы его не засорять. Иногда бывает удобно не создвать имя, скажем, скомпилировать табличку: CREATE zzz 0x100 FOR R@ B, NEXT ;CREATE т.е. цикл FOR выполнится как ему положено 256 раз, и заполнит массив можно создавать несколько имен за раз: 10 FOR VARABLE NEXT one two three ... ten можно писать тесткейсы типа: 10 -IF 24542857 ELSE 67029874 THEN 67029874 <> THROW 10 <> THROW (это для проверки ветвлений) или про создании словарей: Код: init: VOCABULARY VOC-LIST A@ >L \ wordlist ['] sNumLfa L@ off_quest A! 0 L@ off_vtable A! \ отсутствует vtable 0 L@ off_last A! \ слов в словаре нет ['] no-mount L@ off_mount A! ['] no-umount L@ off_umount A! &vinit L> off_vflags B! ;stop NUMBERS В общем, в форке любые ветвления можно использовать за пределами определений
[quote="mgw"]Почему для этого не использовать словарь?[/quote] чтобы его не засорять. Иногда бывает удобно не создвать имя, скажем, скомпилировать табличку:
CREATE zzz 0x100 FOR R@ B, NEXT ;CREATE т.е. цикл FOR выполнится как ему положено 256 раз, и заполнит массив
можно создавать несколько имен за раз:
10 FOR VARABLE NEXT one two three ... ten
можно писать тесткейсы типа: 10 -IF 24542857 ELSE 67029874 THEN 67029874 <> THROW 10 <> THROW (это для проверки ветвлений)
или про создании словарей: [code]init: VOCABULARY VOC-LIST A@ >L \ wordlist ['] sNumLfa L@ off_quest A! 0 L@ off_vtable A! \ отсутствует vtable 0 L@ off_last A! \ слов в словаре нет ['] no-mount L@ off_mount A! ['] no-umount L@ off_umount A! &vinit L> off_vflags B! ;stop NUMBERS[/code]
В общем, в форке любые ветвления можно использовать за пределами определений
|
|
|
|
Добавлено: Вт июл 07, 2015 16:40 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Олег, не могу понять в чем смысл компиляции во временный буфер ( init: ;stop и т.д). Судя по тому, что я понял, это способ, что то скомпилировать "на лету", а потом выполнить. Чуть подробнее о данном механизме расскажи. Почему для этого не использовать словарь?
Олег, не могу понять в чем смысл компиляции во временный буфер ( init: ;stop и т.д). Судя по тому, что я понял, это способ, что то скомпилировать "на лету", а потом выполнить. Чуть подробнее о данном механизме расскажи. Почему для этого не использовать словарь?
|
|
|
|
Добавлено: Пн июл 06, 2015 19:03 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Провел натурные испытания ФортД с Excel (вернее с VBA и VB6). Выяснилось, что Excel имеет только один тип вызова - winapi. Из за этого пришлось добавить несколько функций в forthd.dll Код: import std.c.stdio; import forth; // Forth
export extern (C) void dll_initForth() { initForth(); } export extern (C) void dll_includedForth(char *nameFileForth) { includedForth(nameFileForth); } // Для VBA (Excel, VB6) нужен winapi = Windows export extern (Windows) void dll_winitForth() { initForth(); } export extern (Windows) void dll_wincludedForth(char *nameFileForth) { includedForth(nameFileForth); } export extern (Windows) void dll_setCommonAdr(int n, pp adr) { setCommonAdr(n, adr); } export extern (Windows) void dll_getCommonAdr(int n) { getCommonAdr(n); } export extern (Windows) void dll_evalForth(char *strForth) { evalForth(strForth); } // VBA - делает динамический буфер для строки в момент вызова функции. Для обмана // такого поведения совмещаем две функции Форта с одной для VBA export extern (Windows) void dll_evalForthSetCA(char *strForth, int n, pp adr) { setCommonAdr(n, adr); evalForth(strForth); }
Соответственно проверочный код на Excel VBA Код: Private Declare Sub dll_includedForth Lib "d:\of\forthd.dll" Alias "_dll_wincludedForth@4" (ByVal nameFile As String) Private Declare Sub dll_initForth Lib "d:\of\forthd.dll" Alias "_dll_winitForth@0" () Private Declare Sub dll_setCommonAdr Lib "d:\of\forthd.dll" Alias "_dll_setCommonAdr@8" (ByVal n As Long, ByVal pp As Long) Private Declare Function dll_getCommonAdr Lib "d:\of\forthd.dll" Alias "_dll_getCommonAdr@4" (ByVal n As Long) As Long Private Declare Sub dll_evalForth Lib "d:\of\forthd.dll" Alias "_dll_evalForth@4" (ByVal str As String)
'Обман VBA, фраза [ByVal pp As String] в аргументах заставляет VBA передать адрес строки Private Declare Sub dll_setCommonAdrStr Lib "d:\of\forthd.dll" Alias "_dll_setCommonAdr@8" (ByVal n As Long, ByVal pp As String) 'VBA использует временный буфер для строк, что бы обмануть его и заставаить создать два буфера 'совмещаем в одной операции VBA две операции Форта Private Declare Sub dll_evalForthSetCA Lib "d:\of\forthd.dll" Alias "_dll_evalForthSetCA@12" (ByVal streval As String, ByVal n As Long, ByVal pp As String)
Private Sub CommandButton1_Click() Dim sss As String * 256 Dim buf As String Dim rez As Long sss = "Эта строка из Excel ..." & vbCrLf & vbCrLf & "Да - вызовем вторую часть теста из ForthD" buf = String$(255, 0) 'Буфер под строку Call dll_initForth 'Инициализируем Форт Call dll_includedForth("d:\of\f2.f") 'Компилируем окружение 'Обман VBA, совмещаем 2 операции, заставив сделать два временных буфера под строки Call dll_evalForthSetCA("VAR НоваяСтрока 10 COMMONADR@ НоваяСтрока !", 10, sss) 'В предыдущей строке уже создали переменную под входную строку Call dll_evalForth("0 НоваяСтрока @ S"" Test"" 1+ 3 MessageBox 9 COMMONADR!") rez = dll_getCommonAdr(9) 'Забрать из 9 ячейки результат операции MessageBox If rez = 6 Then 'Нажата кнопка Да Call dll_evalForth(": izm S"" Привет из ForthD"" DUP B@ SWAP 1+ SWAP 11 COMMONADR@ SWAP BMOVE ;") Call dll_evalForthSetCA("izm", 11, buf) MsgBox buf Else MsgBox "Вы отказались от второй части проверки" End If End Sub
Провел натурные испытания ФортД с Excel (вернее с VBA и VB6).
Выяснилось, что Excel имеет только один тип вызова - winapi. Из за этого пришлось добавить несколько функций в forthd.dll
[code] import std.c.stdio; import forth; // Forth
export extern (C) void dll_initForth() { initForth(); } export extern (C) void dll_includedForth(char *nameFileForth) { includedForth(nameFileForth); } // Для VBA (Excel, VB6) нужен winapi = Windows export extern (Windows) void dll_winitForth() { initForth(); } export extern (Windows) void dll_wincludedForth(char *nameFileForth) { includedForth(nameFileForth); } export extern (Windows) void dll_setCommonAdr(int n, pp adr) { setCommonAdr(n, adr); } export extern (Windows) void dll_getCommonAdr(int n) { getCommonAdr(n); } export extern (Windows) void dll_evalForth(char *strForth) { evalForth(strForth); } // VBA - делает динамический буфер для строки в момент вызова функции. Для обмана // такого поведения совмещаем две функции Форта с одной для VBA export extern (Windows) void dll_evalForthSetCA(char *strForth, int n, pp adr) { setCommonAdr(n, adr); evalForth(strForth); } [/code]
Соответственно проверочный код на Excel VBA [code] Private Declare Sub dll_includedForth Lib "d:\of\forthd.dll" Alias "_dll_wincludedForth@4" (ByVal nameFile As String) Private Declare Sub dll_initForth Lib "d:\of\forthd.dll" Alias "_dll_winitForth@0" () Private Declare Sub dll_setCommonAdr Lib "d:\of\forthd.dll" Alias "_dll_setCommonAdr@8" (ByVal n As Long, ByVal pp As Long) Private Declare Function dll_getCommonAdr Lib "d:\of\forthd.dll" Alias "_dll_getCommonAdr@4" (ByVal n As Long) As Long Private Declare Sub dll_evalForth Lib "d:\of\forthd.dll" Alias "_dll_evalForth@4" (ByVal str As String)
'Обман VBA, фраза [ByVal pp As String] в аргументах заставляет VBA передать адрес строки Private Declare Sub dll_setCommonAdrStr Lib "d:\of\forthd.dll" Alias "_dll_setCommonAdr@8" (ByVal n As Long, ByVal pp As String) 'VBA использует временный буфер для строк, что бы обмануть его и заставаить создать два буфера 'совмещаем в одной операции VBA две операции Форта Private Declare Sub dll_evalForthSetCA Lib "d:\of\forthd.dll" Alias "_dll_evalForthSetCA@12" (ByVal streval As String, ByVal n As Long, ByVal pp As String)
Private Sub CommandButton1_Click() Dim sss As String * 256 Dim buf As String Dim rez As Long sss = "Эта строка из Excel ..." & vbCrLf & vbCrLf & "Да - вызовем вторую часть теста из ForthD" buf = String$(255, 0) 'Буфер под строку Call dll_initForth 'Инициализируем Форт Call dll_includedForth("d:\of\f2.f") 'Компилируем окружение 'Обман VBA, совмещаем 2 операции, заставив сделать два временных буфера под строки Call dll_evalForthSetCA("VAR НоваяСтрока 10 COMMONADR@ НоваяСтрока !", 10, sss) 'В предыдущей строке уже создали переменную под входную строку Call dll_evalForth("0 НоваяСтрока @ S"" Test"" 1+ 3 MessageBox 9 COMMONADR!") rez = dll_getCommonAdr(9) 'Забрать из 9 ячейки результат операции MessageBox If rez = 6 Then 'Нажата кнопка Да Call dll_evalForth(": izm S"" Привет из ForthD"" DUP B@ SWAP 1+ SWAP 11 COMMONADR@ SWAP BMOVE ;") Call dll_evalForthSetCA("izm", 11, buf) MsgBox buf Else MsgBox "Вы отказались от второй части проверки" End If End Sub [/code]
|
|
|
|
Добавлено: Сб июн 27, 2015 15:25 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Код: Руководство по компиляции различных вариантов forthD на Linux 32 ( Fedora-21 / 32 )
1 - Программа на С++ по динамической загрузке SO ------------------------------------------------
gcc -omainf2 -fPIC mainf2.c -ldl _________________________________ // mainf2.c // -------- #include <stdio.h> #include <stdlib.h> #include <dlfcn.h>
int main() { void *lh = dlopen("forthd.so", RTLD_LAZY); if (!lh){ fprintf(stderr, "dlopen error: %s\n", dlerror()); exit(1); } typedef int (*dll_initD_t)(void); typedef int (*dll_termD_t)(void); typedef void (*dll_initForth_t)(void); typedef void (*dll_includedForth_t)(char*);
// Имена функций в С++ виде (см файл forthd.cpp) // ------------------------------------------------------------ dll_initD_t dll_initD = dlsym(lh, "_Z9dll_initDv"); if(!dll_initD) printf("!dll_initD\n");
dll_termD_t dll_termD = dlsym(lh, "_Z9dll_termDv"); if(!dll_termD) printf("!dll_termD\n");
dll_initForth_t dll_initForth = dlsym(lh, "_Z13dll_initForthv"); if(!dll_initForth) printf("!dll_initForth\n");
dll_includedForth_t dll_includedForth = dlsym(lh, "_Z17dll_includedForthPc"); if(!dll_includedForth) printf("!dll_includedForth\n");
int a = dll_initD(); dll_initForth(); dll_includedForth((char*)"dll.f"); // Выполнить файл Форта dll_termD();
return 0; }
2 - Обертка для включения Форт в DLL и создание SO --------------------------------------------------
dmd -c forth.d -release // Сам форт dmd -c forthd.d -fPIC -release // Обертка для DLL // Сборка SO dmd -shared -offorthd.so forthd.o forth.o -defaultlib=libphobos2.so _________________________________ // forthd.d // --------
import std.c.stdio; import core.runtime; import std.stdio; import forth;
export extern (C++) int dll_initD() { return rt_init(); } export extern (C++) int dll_termD() { return rt_term(); } export extern (C++) void dll_initForth() { forth.initForth(); } export extern (C++) void dll_includedForth(char *nameFileForth) { setCommonAdr(1, cast(pp)&fputc); includedForth(nameFileForth); }
3 - Переносимость Форт SO в другой каталог -----------------------------------------
Необходимы: forthd.so libphobos2.so LD_LIBRARY_PATH=`pwd`; export LD_LIBRARY_PATH _________________________________ // testforth.f // --------
\ Проверка работы forthd на SPF4 \ ------------------------------ Library" forthd.so" fd Library@ fd 0 CDECL-Call" _Z9dll_initDv" dll_initD Library@ fd 0 CDECL-Call" _Z9dll_termDv" dll_termD Library@ fd 0 CDECL-Call" _Z13dll_initForthv" dll_initForth Library@ fd 1 CDECL-Call" _Z17dll_includedForthPc" dll_includedForth LibraryLoad fd : test dll_initD DROP dll_initForth S" dll.f" DROP dll_includedForth dll_termD DROP ; test
4 - Статическая компиляция forthd и C++ ---------------------------------------
dmd -c forth.d -release // Сам форт dmd -c forthd.d -release // Обертка для DLL gcc main_c1.cpp forthd.o forth.o libphobos2.a -lpthread -o main_c1 -ldl _________________________________ // main_c1.cpp // --------
int dll_initD(); // Инициализация D int dll_termD(); // Деинициализация D void dll_initForth(); // Инициализация Форта void dll_includedForth(char *nameFileForth); // Выполнить файл Форта
int main(void) { int a = dll_initD(); dll_initForth(); dll_includedForth((char*)"dll.f"); // Выполнить файл Форта dll_termD(); return 0; }
[code] Руководство по компиляции различных вариантов forthD на Linux 32 ( Fedora-21 / 32 )
1 - Программа на С++ по динамической загрузке SO ------------------------------------------------
gcc -omainf2 -fPIC mainf2.c -ldl _________________________________ // mainf2.c // -------- #include <stdio.h> #include <stdlib.h> #include <dlfcn.h>
int main() { void *lh = dlopen("forthd.so", RTLD_LAZY); if (!lh){ fprintf(stderr, "dlopen error: %s\n", dlerror()); exit(1); } typedef int (*dll_initD_t)(void); typedef int (*dll_termD_t)(void); typedef void (*dll_initForth_t)(void); typedef void (*dll_includedForth_t)(char*);
// Имена функций в С++ виде (см файл forthd.cpp) // ------------------------------------------------------------ dll_initD_t dll_initD = dlsym(lh, "_Z9dll_initDv"); if(!dll_initD) printf("!dll_initD\n");
dll_termD_t dll_termD = dlsym(lh, "_Z9dll_termDv"); if(!dll_termD) printf("!dll_termD\n");
dll_initForth_t dll_initForth = dlsym(lh, "_Z13dll_initForthv"); if(!dll_initForth) printf("!dll_initForth\n");
dll_includedForth_t dll_includedForth = dlsym(lh, "_Z17dll_includedForthPc"); if(!dll_includedForth) printf("!dll_includedForth\n");
int a = dll_initD(); dll_initForth(); dll_includedForth((char*)"dll.f"); // Выполнить файл Форта dll_termD();
return 0; }
2 - Обертка для включения Форт в DLL и создание SO --------------------------------------------------
dmd -c forth.d -release // Сам форт dmd -c forthd.d -fPIC -release // Обертка для DLL // Сборка SO dmd -shared -offorthd.so forthd.o forth.o -defaultlib=libphobos2.so _________________________________ // forthd.d // --------
import std.c.stdio; import core.runtime; import std.stdio; import forth;
export extern (C++) int dll_initD() { return rt_init(); } export extern (C++) int dll_termD() { return rt_term(); } export extern (C++) void dll_initForth() { forth.initForth(); } export extern (C++) void dll_includedForth(char *nameFileForth) { setCommonAdr(1, cast(pp)&fputc); includedForth(nameFileForth); }
3 - Переносимость Форт SO в другой каталог -----------------------------------------
Необходимы: forthd.so libphobos2.so LD_LIBRARY_PATH=`pwd`; export LD_LIBRARY_PATH _________________________________ // testforth.f // --------
\ Проверка работы forthd на SPF4 \ ------------------------------ Library" forthd.so" fd Library@ fd 0 CDECL-Call" _Z9dll_initDv" dll_initD Library@ fd 0 CDECL-Call" _Z9dll_termDv" dll_termD Library@ fd 0 CDECL-Call" _Z13dll_initForthv" dll_initForth Library@ fd 1 CDECL-Call" _Z17dll_includedForthPc" dll_includedForth LibraryLoad fd : test dll_initD DROP dll_initForth S" dll.f" DROP dll_includedForth dll_termD DROP ; test
4 - Статическая компиляция forthd и C++ ---------------------------------------
dmd -c forth.d -release // Сам форт dmd -c forthd.d -release // Обертка для DLL gcc main_c1.cpp forthd.o forth.o libphobos2.a -lpthread -o main_c1 -ldl _________________________________ // main_c1.cpp // --------
int dll_initD(); // Инициализация D int dll_termD(); // Деинициализация D void dll_initForth(); // Инициализация Форта void dll_includedForth(char *nameFileForth); // Выполнить файл Форта
int main(void) { int a = dll_initD(); dll_initForth(); dll_includedForth((char*)"dll.f"); // Выполнить файл Форта dll_termD(); return 0; } [/code]
|
|
|
|
Добавлено: Пн июн 22, 2015 11:30 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Под впечатлением от безуспешной попытки победить mingw компилятор, решил вернуться к проверенному решению, а именно D. Предлагаю оценить DLL (forth.dll) в которой представлен Forth реализация на D. В качестве базы (архитектура базовых слов) Fork mOlega (ему огромное спасибо за Fork). https://yadi.sk/d/73Pr-9JihN5Z2 Архив содержит: testForth.cpp - простенькая прога на C++ (symantec 7.2), для проверки работы fortdll.dll запуск: TestForth f2.f f2.f - Текст форт программы для проверки работы. В основном загрузка DLL и проверка работы функций из них stdlib.f - Текст форт модуля для работы с DLL. Вызывается из f2.f testLinux.txt - Текстовый файл, создается форт программой используя функции из CrtDLL MS forthdll.dll - Dll содержащия Forth реализацию на D mydll.d - исходный текст на D для forthdll.dll forth.d - исходный модуль на D для Forth
Под впечатлением от безуспешной попытки победить mingw компилятор, решил вернуться к проверенному решению, а именно D.
Предлагаю оценить DLL (forth.dll) в которой представлен Forth реализация на D. В качестве базы (архитектура базовых слов) Fork mOlega (ему огромное спасибо за Fork).
https://yadi.sk/d/73Pr-9JihN5Z2
Архив содержит: testForth.cpp - простенькая прога на C++ (symantec 7.2), для проверки работы fortdll.dll запуск: TestForth f2.f f2.f - Текст форт программы для проверки работы. В основном загрузка DLL и проверка работы функций из них stdlib.f - Текст форт модуля для работы с DLL. Вызывается из f2.f testLinux.txt - Текстовый файл, создается форт программой используя функции из CrtDLL MS forthdll.dll - Dll содержащия Forth реализацию на D mydll.d - исходный текст на D для forthdll.dll forth.d - исходный модуль на D для Forth
|
|
|
|
Добавлено: Сб июн 20, 2015 15:11 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Пытаюсь смоделировать inline asm вставку на mingw. Не получается ((( Код: extern "C" Q_DECL_EXPORT __attribute__((naked)) void testAsm(void) { asm ( "mov $3, %eax\n" ); }
Компилятор упорно вставляет пролог/эпилог, любезно сообщая, что атрибут naked он проигнорировал. На выходе код: Код: public testAsm testAsm proc near // Пролог push ebp mov ebp, esp // --------------- mov eax, 3 // --------------- // Эпилог leave retn testAsm endp
Как от этого избавится, не представляю .... Пока в голову лезет только подход форта. А именно, берем код и записываем как массив байтов. Этот массив байтов объявляем функцией. А дальше все как обычно ... Код: char buf[] = { 0x55,0x89,0xE5,0xB8,0x03,0x00,0x00,0x00,0xC9,0xC3 };
typedef int (* test_t)(void); test_t testAsm3 = (test_t)&buf;
extern "C" Q_DECL_EXPORT int testAsm2(void) { return testAsm3(); // выполним функцию, собранную из массива байтов }
Пытаюсь смоделировать inline asm вставку на mingw. Не получается ((( [code] extern "C" Q_DECL_EXPORT __attribute__((naked)) void testAsm(void) { asm ( "mov $3, %eax\n" ); } [/code]
Компилятор упорно вставляет пролог/эпилог, любезно сообщая, что атрибут naked он проигнорировал.
На выходе код: [code] public testAsm testAsm proc near // Пролог push ebp mov ebp, esp // --------------- mov eax, 3 // --------------- // Эпилог leave retn testAsm endp [/code]
Как от этого избавится, не представляю ....
Пока в голову лезет только подход форта. А именно, берем код и записываем как массив байтов. Этот массив байтов объявляем функцией. А дальше все как обычно ...
[code] char buf[] = { 0x55,0x89,0xE5,0xB8,0x03,0x00,0x00,0x00,0xC9,0xC3 };
typedef int (* test_t)(void); test_t testAsm3 = (test_t)&buf;
extern "C" Q_DECL_EXPORT int testAsm2(void) { return testAsm3(); // выполним функцию, собранную из массива байтов } [/code]
|
|
|
|
Добавлено: Пт июн 19, 2015 19:40 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Столкнулся с интересной ситуацией. Раньше об этом не задумывался: Компилятор D (dmd 2.067) для Win написан на C++ Symantec 8.xx и соответственно цепляет RunTime собственной сборки. Я через форт (фактически через C++ Symantec RunTime) гружу в динамике ctrdll.dll, который есть производство MS. Хочу просто воспользоваться функциями типа fputc, fputs и т.д. Для этого нужен указатель на структуру FILE, например классический "stdout", и получаю ошибку! Выясняется, что разные компиляторы C++ имеют разный состав и соответственно размер этих структур и соответственно не совместимы. Получается, что я не могу воспользоваться многими DLL из Windows. В общем, пытаюсь найти указатель на MS FILE в ctrdll.dll ... Ответ найден:Есть глобальный указатель на буфера *FILE в MS crt.dll. Если взять ссылку на них, то можно добраться до MS stdout, stdin и т.д. Код: // Проверим Windows IF=W Lib" CRTDLL.DLL" CrtDll IF=W Library@ CrtDll 1 CDECL-Call" strlen" strlen IF=W Library@ CrtDll 2 CDECL-Call" strcmp" strcmp IF=W Library@ CrtDll 1 CDECL-Call" strncmp" strncmp IF=W Library@ CrtDll 2 CDECL-Call" fputc" putc IF=W Library@ CrtDll 1 CDECL-Call" _fputchar" _fputchar IF=W Library@ CrtDll 2 CDECL-Call" fputwc" fputwc IF=W Library@ CrtDll 2 CDECL-Call" fputs" fputs IF=W Library@ CrtDll 2 CDECL-Call" fputwc" fputwc IF=W Library@ CrtDll 1 CDECL-Call" fgetwc" fgetwc IF=W Library@ CrtDll 2 CDECL-Call" fopen" fopen IF=W Library@ CrtDll 1 CDECL-Call" fclose" fclose IF=W Library@ CrtDll 0 GADR-Call" _iob" ms6_iob
IF=W LibraryLoad CrtDll
// Переменные хранящие указатели на открытые файлы VAR v_STDOUT // stdout VAR v_STDIN // stdin VAR v_STDERR // stderr
IF=L (STDOUT) v_STDOUT ! // В Linux stdout == С++ gcc
// [u]Вот сами буфера[/u] IF=W ms6_iob 32 + v_STDOUT ! // В Winows stdout получаем непосредственно из _iob[1]; IF=W ms6_iob v_STDIN ! // В Winows stdin получаем из _iob[0];
// Моделирую работу с консолью через функции библиотеки stdc : EMIT v_STDOUT @ putc DROP ; // ( N -- ) Вывод символа на стандартный вывод
: F_EMIT // ( File N -- ) Вывести символ в файл SWAP putc DROP ; : CR // ( -- ) Перевод строки IF=W 13 EMIT 10 EMIT ; : TYPE // ( Astrz N -- ) Напечатать строку DUP B@ BEGIN DUP WHILE SWAP 1+ DUP B@ EMIT SWAP 1- REPEAT DROP DROP ; S" ----------4---------" TYPE CR : F_TYPE // ( File Astrz -- ) Напечатать строку в файл SWAP >R DUP B@ BEGIN DUP WHILE SWAP 1+ DUP B@ R@ SWAP F_EMIT SWAP 1- REPEAT DROP DROP RDROP ;
Столкнулся с интересной ситуацией. Раньше об этом не задумывался:
Компилятор D (dmd 2.067) для Win написан на C++ Symantec 8.xx и соответственно цепляет RunTime собственной сборки. Я через форт (фактически через C++ Symantec RunTime) гружу в динамике ctrdll.dll, который есть производство MS. Хочу просто воспользоваться функциями типа fputc, fputs и т.д. Для этого нужен указатель на структуру FILE, например классический "stdout", и получаю ошибку! Выясняется, что разные компиляторы C++ имеют разный состав и соответственно размер этих структур и соответственно не совместимы. Получается, что я не могу воспользоваться многими DLL из Windows. В общем, пытаюсь найти указатель на MS FILE в ctrdll.dll ...
[u]Ответ найден:[/u]
Есть глобальный указатель на буфера *FILE в MS crt.dll. Если взять ссылку на них, то можно добраться до MS stdout, stdin и т.д.
[code] // Проверим Windows IF=W Lib" CRTDLL.DLL" CrtDll IF=W Library@ CrtDll 1 CDECL-Call" strlen" strlen IF=W Library@ CrtDll 2 CDECL-Call" strcmp" strcmp IF=W Library@ CrtDll 1 CDECL-Call" strncmp" strncmp IF=W Library@ CrtDll 2 CDECL-Call" fputc" putc IF=W Library@ CrtDll 1 CDECL-Call" _fputchar" _fputchar IF=W Library@ CrtDll 2 CDECL-Call" fputwc" fputwc IF=W Library@ CrtDll 2 CDECL-Call" fputs" fputs IF=W Library@ CrtDll 2 CDECL-Call" fputwc" fputwc IF=W Library@ CrtDll 1 CDECL-Call" fgetwc" fgetwc IF=W Library@ CrtDll 2 CDECL-Call" fopen" fopen IF=W Library@ CrtDll 1 CDECL-Call" fclose" fclose IF=W Library@ CrtDll 0 GADR-Call" _iob" ms6_iob
IF=W LibraryLoad CrtDll
// Переменные хранящие указатели на открытые файлы VAR v_STDOUT // stdout VAR v_STDIN // stdin VAR v_STDERR // stderr
IF=L (STDOUT) v_STDOUT ! // В Linux stdout == С++ gcc
// [u]Вот сами буфера[/u] IF=W ms6_iob 32 + v_STDOUT ! // В Winows stdout получаем непосредственно из _iob[1]; IF=W ms6_iob v_STDIN ! // В Winows stdin получаем из _iob[0];
// Моделирую работу с консолью через функции библиотеки stdc : EMIT v_STDOUT @ putc DROP ; // ( N -- ) Вывод символа на стандартный вывод
: F_EMIT // ( File N -- ) Вывести символ в файл SWAP putc DROP ; : CR // ( -- ) Перевод строки IF=W 13 EMIT 10 EMIT ; : TYPE // ( Astrz N -- ) Напечатать строку DUP B@ BEGIN DUP WHILE SWAP 1+ DUP B@ EMIT SWAP 1- REPEAT DROP DROP ; S" ----------4---------" TYPE CR : F_TYPE // ( File Astrz -- ) Напечатать строку в файл SWAP >R DUP B@ BEGIN DUP WHILE SWAP 1+ DUP B@ R@ SWAP F_EMIT SWAP 1- REPEAT DROP DROP RDROP ;
[/code]
|
|
|
|
Добавлено: Ср июн 17, 2015 17:08 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
mOleg писал(а): Зачем брать так высоко, а? Нет, я не спорю со сказанным выше, но зачем же из пушки по воробъям-то? Вот, скажем, известно, что поиск по линейному списку проще реализуется, чем, скажем, хешированный, но хешированный значительно быстрее. При написании очередной системы, конечно, можно написать бизнес план и т.д. Но стоит ли ради двух дополнительных определений так напрягаться? Когда человек видит велосипедиста, он может и на глаз прикинуть, как с ним не столкнуться. А вот когда запускается спутник, прикидками на глазок уже не обойтись. Формализация требуется тем больше, чем сложнее для восприятия становится программа. Иначе сегодня примем решение делать ассемблерную вставку, а через неделю - применить медленную, зато кроссплатформенную библиотеку. В обоих случаях будет и обоснование - "потому что производительность", "потому что кроссплатформенность", но в совокупности не будет ни того, ни другого. Кстати, и показательный вопрос/пример. Сложность y=kx и y = kx^2 - кто эффективнее?
[quote="mOleg"]Зачем брать так высоко, а? Нет, я не спорю со сказанным выше, но зачем же из пушки по воробъям-то? Вот, скажем, известно, что поиск по линейному списку проще реализуется, чем, скажем, хешированный, но хешированный значительно быстрее. При написании очередной системы, конечно, можно написать бизнес план и т.д. Но стоит ли ради двух дополнительных определений так напрягаться?[/quote] Когда человек видит велосипедиста, он может и на глаз прикинуть, как с ним не столкнуться. А вот когда запускается спутник, прикидками на глазок уже не обойтись. Формализация требуется тем больше, чем сложнее для восприятия становится программа. Иначе сегодня примем решение делать ассемблерную вставку, а через неделю - применить медленную, зато кроссплатформенную библиотеку. В обоих случаях будет и обоснование - "потому что производительность", "потому что кроссплатформенность", но в совокупности не будет ни того, ни другого. Кстати, и показательный вопрос/пример. Сложность y=kx и y = kx^2 - кто эффективнее?
|
|
|
|
Добавлено: Вт июн 16, 2015 22:38 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Hishnik писал(а): Концепция продукта в данном случае (возможной) частной реализации алгоритма. Hishnik писал(а): Сначала определяется цель Зачем брать так высоко, а? Нет, я не спорю со сказанным выше, но зачем же из пушки по воробъям-то? Вот, скажем, известно, что поиск по линейному списку проще реализуется, чем, скажем, хешированный, но хешированный значительно быстрее. При написании очередной системы, конечно, можно написать бизнес план и т.д. Но стоит ли ради двух дополнительных определений так напрягаться?
[quote="Hishnik"] Концепция продукта[/quote] в данном случае (возможной) частной реализации алгоритма.
[quote="Hishnik"]Сначала определяется цель [/quote] Зачем брать так высоко, а? Нет, я не спорю со сказанным выше, но зачем же из пушки по воробъям-то? Вот, скажем, известно, что поиск по линейному списку проще реализуется, чем, скажем, хешированный, но хешированный значительно быстрее. При написании очередной системы, конечно, можно написать бизнес план и т.д. Но стоит ли ради двух дополнительных определений так напрягаться?
|
|
|
|
Добавлено: Вт июн 16, 2015 22:04 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
mOleg писал(а): Заявлена не концепция, а идея, в чем-то спорная, в чем-то проблемная, реализации пока нет. Обсуждать можно многое, в том числе размер буфера, отводимого под определение, только параметр таки третьестепенный и легко настраиваемый. А вопрос тут не в том, насколько легко оно настраивается. Концепция продукта состоит не в том, сколько параметров на стеке у него при вызове функции ОС или сколько байт в буфере. Сначала определяется цель - например, повысить скорость работы, или сделать кроссплатформенный транслятор, или Форт с повышенной надежностью в рантайме. И с этой целью уже согласовываются конкретные решения. Например, надо ли делать ассемблерную вставку? С точки зрения профессионализма - да, это круто. С точки зрения цели интереснее. Если надо сделать быстрый код, то скорее надо. Если кроссплатформенный - то точно не надо, или же надо озаботиться написанием таких вставок для всех используемых процессоров. Добавление вспомогательных инструментов тоже неоднозначно. Вот в трансляторе накопилось 7 различных вспомогательных буферов, каждый из которых легко настраивается, если его вдруг не хватит. Эти буферы начинают в процессе работы по очереди переполняться, программист чертыхается и постоянно пересобирает Форт. Каким образом надо позиционировать такой продукт?
[quote="mOleg"]Заявлена не концепция, а идея, в чем-то спорная, в чем-то проблемная, реализации пока нет. Обсуждать можно многое, в том числе размер буфера, отводимого под определение, только параметр таки третьестепенный и легко настраиваемый.[/quote] А вопрос тут не в том, насколько легко оно настраивается. Концепция продукта состоит не в том, сколько параметров на стеке у него при вызове функции ОС или сколько байт в буфере. Сначала определяется цель - например, повысить скорость работы, или сделать кроссплатформенный транслятор, или Форт с повышенной надежностью в рантайме. И с этой целью уже согласовываются конкретные решения. Например, надо ли делать ассемблерную вставку? С точки зрения профессионализма - да, это круто. С точки зрения цели интереснее. Если надо сделать быстрый код, то скорее надо. Если кроссплатформенный - то точно не надо, или же надо озаботиться написанием таких вставок для всех используемых процессоров. Добавление вспомогательных инструментов тоже неоднозначно. Вот в трансляторе накопилось 7 различных вспомогательных буферов, каждый из которых легко настраивается, если его вдруг не хватит. Эти буферы начинают в процессе работы по очереди переполняться, программист чертыхается и постоянно пересобирает Форт. Каким образом надо позиционировать такой продукт?
|
|
|
|
Добавлено: Вт июн 16, 2015 21:18 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Hishnik писал(а): Сложность тут исключительно в том, что при отсутствии четко заявленной концепции продукта он начинает "расползаться". Ежели честно, ничего не понял 8( Заявлена не концепция, а идея, в чем-то спорная, в чем-то проблемная, реализации пока нет. Обсуждать можно многое, в том числе размер буфера, отводимого под определение, только параметр таки третьестепенный и легко настраиваемый.
[quote="Hishnik"]Сложность тут исключительно в том, что при отсутствии четко заявленной концепции продукта он начинает "расползаться".[/quote] Ежели честно, ничего не понял 8( Заявлена не концепция, а идея, в чем-то спорная, в чем-то проблемная, реализации пока нет. Обсуждать можно многое, в том числе размер буфера, отводимого под определение, только параметр таки третьестепенный и легко настраиваемый.
|
|
|
|
Добавлено: Вт июн 16, 2015 21:01 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
mOleg писал(а): а потому что не проблема ни разу. Вариантов разрешения куча, а сложности реализации совсем в другом месте. Сложность тут исключительно в том, что при отсутствии четко заявленной концепции продукта он начинает "расползаться". Как в анекдоте - "новые вагоны быстрые, удобные и бесшумные. Одни быстрые, другие удобные, третьи бесшумные". Так и тут получается - слова Форта быстрые, надежные, понятные и компактные...
[quote="mOleg"]а потому что не проблема ни разу. Вариантов разрешения куча, а сложности реализации совсем в другом месте.[/quote] Сложность тут исключительно в том, что при отсутствии четко заявленной концепции продукта он начинает "расползаться". Как в анекдоте - "новые вагоны быстрые, удобные и бесшумные. Одни быстрые, другие удобные, третьи бесшумные". Так и тут получается - слова Форта быстрые, надежные, понятные и компактные... :)
|
|
|
|
Добавлено: Пт июн 12, 2015 00:21 |
|
|
|
|
|
Заголовок сообщения: |
Re: Forth на inline asm. Это реально? |
|
|
Hishnik писал(а): Почему только 64? И почему гигабайт? а потому что не проблема ни разу. Вариантов разрешения куча, а сложности реализации совсем в другом месте. Hishnik писал(а): Да, можно. Только Имхо, тут лишь в качество документации все упирается. Ethereal писал(а): На форуме же есть раздел "Форт для микроконтроллеров" так это не подходит для микроконтроллера (маленького), а, вот, для связки контроллер + PC уже вкусно выглядит. Т.к. буфер этот может быть как раз на PC, а в контроллер будет копироваться уже оптимизированный вариант. Ethereal писал(а): Только ее типично 1 килобайт ОЗУ и это на "жирненьких" чипах. собственно, ответ выше уже дан.
[quote="Hishnik"]Почему только 64? И почему гигабайт? [/quote] а потому что не проблема ни разу. Вариантов разрешения куча, а сложности реализации совсем в другом месте.
[quote="Hishnik"]Да, можно. Только [/quote] Имхо, тут лишь в качество документации все упирается.
[quote="Ethereal"]На форуме же есть раздел "Форт для микроконтроллеров"[/quote] так это не подходит для микроконтроллера (маленького), а, вот, для связки контроллер + PC уже вкусно выглядит. Т.к. буфер этот может быть как раз на PC, а в контроллер будет копироваться уже оптимизированный вариант.
[quote="Ethereal"]Только ее типично 1 килобайт ОЗУ и это на "жирненьких" чипах.[/quote] собственно, ответ выше уже дан.
|
|
|
|
Добавлено: Чт июн 11, 2015 19:50 |
|
|
|
|