( ) sar sal/shl shr ror rol rcl rcr and xor or neg not * / mod + - Кажется так... (ред) арифметический сдвиг забыл и плюс на второе место влупил )
Здрастуйте. Дошло спустя четыре месяца. Хочу поделиться и тут(на другом форуме тема). Не пойму деления, а именно _ulldiv PROC, метка big_divisor. Следовательно /(div) и %(mod) отсутствуют. Все детали в \calc\calc.inc. Вы поймете, что главная процедура предельно проста. Никаких вычислений сама не производит - все делают расширения пользователя. Там вы найдете макро, а в нем написано "nothing displayed, is this possible?"(ничего не показывает или я туплю). Откомментируйте строчку выше - выскакивает, мол метод ровен нулю, хотя нет. Кто знает, где я неправ. Пожалсто дайте теории (и)ли сам метод деления. С приоритетами большой спор, не знаю, писал с фасма и наугад. Предложите ваши методы времени вычисления(см. архив). Спасибо. Архив тут: http://code.google.com/p/fasmme/downloads/detail?name=calc.zip&can=2&q= или тут: http://code.google.com/p/fasmme/downloads/detail?name=calc.rar&can=2&q=
edemko Есть у меня книжка быстрые алгоритмы ... Так там много математических финтов описано. Пусть надо умножить два 64 битных числа a на b; y=a*b a=[a1:a0] b=[b1:b0] y=[y1:y0] V0=1*a1+1*a2; V1=1*a1+w1*a2; U0=1*b1+1*b2; U1=1*b1+w1*b2; R0=V0*U0 R1=V1*U1 y0=(1*R0+1*R1)/2 y1=(1*R0+w1*R1)/2 Так вот дальше тут вопрос оптимизации. Деление делается аналогично. Дальше выкладки пойдут в других обозначениях, так что если не совпадут с предыдущим так это потому что не связаны. a=y/b R0=1*y0+1*y1 R1=1*y0+w1*y1 U0=1*b0+1*b1 U1=1*b0+w1*b1 V0=R0/U0 // вот оно деление тут может быть потеря точности V1=R1/U1 // и алгоритм окажется приближенным a0=(1*V0+1*V1)/2 a1=(1*V0+w1*V1)/2 Здесь во всех выкладках w1=-1 А да еще тут надо отследить переполнение при сложение. Для удобства деление на 2 можно делать сразу а не в конце. А доказательство что это правильно основано на высшей математике, так что тут врятли, кто его поймёт так что не привожу.
DoctorWho По поводу приоритетов. Не правильно. Возьмем or и and. Они аналогичны * и + Поэтому у or приоритет больше. А у not еще больше так как считается унарной операцией. А вообще в интернете легкой найти табличку приоритетов операций в C++. Только там не только битовые or, но и логический.
Тут мысли в слух. Есть предположение что деление можно сделать через инвертирование порядка бит, что будет выполняться еще быстрее.
? можете? p.s.: некоторые речи без ответов, но это не значит, что я их упустил, спасибо мама спортила нервы, но метку упростил, тест версия Код (Text): ;dvd -> edx:ecx ;dvs -> ebx:eax ;ebx:eax <- 0:quo ;edx,ecx <- ? ;flags <- ? push edi push 0 0 ;dvd.dump & dvs.dump xchg ecx,eax ;edx:ecx/ebx:eax -> edx:eax/ebx:ecx mov edi,ecx bsr ecx,ebx shrd [esp],edi,cl ;dvs.dump shrd edi,ebx,cl shr ebx,cl shr ebx,1 rcr edi,1 ;dvs = $8000'0000..$ffff'ffff rcr dword[esp],1 ;dvs.dump shrd [esp+4],eax,cl ;dvd.dump shrd eax,edx,cl shr edx,cl shr edx,1 rcr eax,1 ;dvd = $8000'0000..$7fff'ffff'ffff'ffff rcr dword[esp+4],1 ;dvd.dump div edi ;quo < 2^32 pop ecx edx ;dvs.dump & dvd.dump cmp edx,ecx sbb eax,ebx ;) = pop edi ; $ffff'ffff'ffff'ffff / $0000'0001'ffff'ffff вот так с помощью макро прожка получает поддержку 8 методов Код (Text): ; form: value {rolb,rolw,rold,rolq,rorb,rorw,rord,rorq} value macro rocknroll[name,instro]{ forward label name cmp ebx,1 jne name#_nok cmp eax,ebx jne name#_nok add edi,9+1 mov cl,[ecx+9+1] if ~name eq .rolq & ~name eq .rorq instro [edi],cl add edi,8 ;clc else and cl,63 cmp cl,32 mov ebx,[edi+4] mov eax,[edi] jb name#_cl_b_32 xchg ebx,eax sub cl,32 name#_cl_b_32: mov edx,ebx instro ebx,eax,cl instro eax,edx,cl stosd mov eax,ebx stosd clc end if ret 0 name#_nok: stc ret 0 } rocknroll .rolb, rol byte,\ .rolw, rol word,\ .rold, rol dword,\ .rorb, ror byte,\ .rorw, ror word,\ .rord, ror dword,\ .rolq, shld,\ .rorq, shrd purge rocknroll p.s.: value - значение form - форма dvd - делимое dvs - делитель quo - остаток dump - остаток
Конечный код: Код (Text): ; ebx:eax <- edx:ecx div ebx:eax ; edx:ecx <- edx:ecx mod ebx:eax ; flags <- xor reg32,reg32 proc .div cmp ebx,edx ja .div_result_0 jb .div_result_!0 cmp eax,ecx jna .div_result_!0 .div_result_0: ;dvd < dvs xor ebx,ebx xor eax,eax ret 0 .div_result_!0: test ebx,ebx jnz .div_divisor.h_nz test eax,eax jnz .div_divisor.l_nz xor edx,edx ;dvs = 0 xor ecx,ecx ret 0 .div_divisor.l_nz: ;sizeof.quo = 64 bit, sizeof.rem = 32 bit mov ebx,eax mov eax,edx xor edx,edx div ebx ;quo.h xchg ecx,eax div ebx ;quo.l mov ebx,ecx mov ecx,edx xor edx,edx ret 0 .div_divisor.h_nz: ;sizeof.quo = 32 bit, sizeof.rem = 64 bit test eax,eax jnz .div_none_z mov eax,edx xor edx,edx div ebx xor ebx,ebx ret 0 .div_none_z: ;sizeof.quo = 32 bit, sizeof.rem = 64 bit push edi push edx ecx ebx eax ;=======================;DIV= push 0 0 ;dvd.dump & dvs.dump mov edi,eax mov eax,ecx ;edx:ecx/ebx:eax -> edx:eax/ebx:edi bsr ecx,ebx shrd [esp],edi,cl ;dvs.dump shrd edi,ebx,cl shr ebx,cl shr ebx,1 rcr edi,1 ;dvs = $8000'0000..$ffff'ffff rcr dword[esp],1 ;dvs.dump shrd [esp+4],eax,cl ;dvd.dump shrd eax,edx,cl shr edx,cl shr edx,1 rcr eax,1 ;dvd = $8000'0000..$7fff'ffff'ffff'ffff rcr dword[esp+4],1 ;dvd.dump div edi ;quo < 2^32 pop ecx edx ;dvs.dump & dvd.dump cmp edx,ecx sbb eax,ebx ;) = ;=======================;MOD= mov ebx,eax pop edx mul edx pop edi pop ecx sub ecx,eax ;mod.l mov eax,edi pop edi sbb edi,edx mul ebx sub edi,eax mov edx,edi ;mod.h mov eax,ebx xor ebx,ebx pop edi ret 0 ;2010_12_28 ; $ffff'ffff'ffff'ffff / $0000'0001'ffff'ffff ; $ffff'ffff'ffff'ffff / $ffff'ffff'ffff'fffe endp Отсюда поддержка новых операторов - 'div','/' и 'mod','%': Код (Text): ; form1: val div val ; form2: val / val .div1: cmp ebx,1 jne .div1_nok cmp eax,ebx jne .div1_nok mov ebx,[ecx+9+1+4] mov eax,[ecx+9+1] add edi,10 mov edx,[edi+4] mov ecx,[edi] call .div stosd mov eax,ebx stosd ret 0 .div1_nok: stc ret 0 ; form1: val mod val ; form2: val % val .mod: cmp ebx,1 jne .mod_nok cmp eax,ebx jne .mod_nok mov ebx,[ecx+9+1+4] mov eax,[ecx+9+1] add edi,10 mov edx,[edi+4] mov ecx,[edi] call .div mov eax,ecx stosd mov eax,edx stosd ret 0 .mod_nok: stc ret 0
Дописал. На сегодня поддерживает методы: Код (Text): movd movq packssd packssw packusw paddb paddd paddsb paddsw paddusb paddusw paddw pand pandn pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pmaddwd pmulhw pmullw por pslld psllq psllw psrld psrlq psrlw psubb psubd psubsb psubsw psubusb psubusw psubw punpckh punpckh punpckh punpckl punpckl punpckl pxor + - bsf, bsl bsr byte sbyte word sword dword sdword * ** *** /, div %, mod &, and |, or ^ xor rolb rolw rold rorb rorw rord rolq rorq >>>, sar <<, shl >>, shr shld shrd shlq shrq ~, neg !, not 1/, rcp Следующие формы вывода результата: Код (Text): двоичный десятичный шестнадцатеричный знаковый десятичный строковый двоичная-в-десятичную дробь строкой Ссылка для загрузки: http://code.google.com/p/fasmme/downloads/detail?name=calc.rar&can=2&q=
Привет форум! В модуль добавлена тестовая поддержка fpu те. дробных чисел. Писалось от 1'го января 2011 года, падений покась не увидел. Но в прошлой версии ошибки были: разрешалась 16'ричная десятка в десятичной записи; неправильно обрабатывальсь пустые блоки типа (). Часть комментария к get_number: Код (Text): ; rus: считать строку в беззнаковое число ; поддерживаются двоичные(нап. 0b), десятичные(нап. 0 или 0d или 0D), шестнадцатеричные(нап. $0 или 0x0 или 0X0), строковые(нап. '''', """", 'строка', "как'есть") qword-числа ; нуль-завершенная-строка -> esi ; временный буфер -> edi ; flags.df -> 0 ; "невидимый" символ -> ah ; используйте для удобности чтения(1'024 итд.), если ноль - игнорится ; eax,ebx,ecx,edx <- ? ; esi,edi <- сдвинуты за конец строки и полученого qword-числа соответственно ; flags.cf <- 1 если ошибка(в этом случае esi,edi также неопределены) ; ; Д О Р А Б О Т К А : ; функция поддерживает tbyte-числа, будучи совместимой с режимом qword выше, следовательно результат занимает 10 байт ; поддерживаемые формы записи(нап.): 0b, 0d, 0D, ,d, ,D, .d, .D, 0,d, 0,D, 0.d, 0.D, 0,0d, 0,0D, 0.0d, 0.0D, 1,e+-1, 1.E--1d, ляпота, $0, 0x0, 0X0, "''строкой""" ; eax.последний_бит(31) -> выставьте в 1 для перехода в режим чисел с плавающей запятой ; fpu.st5..7 -> вдостоверьтесь в их доступности ; fpu.tos <- стек восстанавливает?ся ; proc get_number ;2011_01_01 lodsb cmp al,1 jnc @f ret 0 ;конец строки так сразу @@: xor ecx,ecx ;число отфильтрованных символом cmp al,'"' je .raw ;как есть cmp al,"'" je .raw ;как есть ... Несколько неоттестированых методов fpu: Код (Text): ; form1: -v2 ; form2: v1-v2 .fsub: cmp ebx,1 jne .fsub_nok ;ошибочно параметров справа cmp eax,ebx ja .fsub_nok ;ошибочно параметров слева lea edi,[edi+11] ;ок, пропустить пустышку mov al,2 ;сказать "о да, я число :)" stosb fld tbyte[ecx+11+1] ;загрузить первый правый параметр je .fsub_pair ;так параметров два? - будем вычитать fchs ;иначе только изменим знак .fsub_store: fstp tbyte[edi] ;запишем значение add edi,10 ;сместим указатель за тело ret 0 ;flags.cf очищен предыдущей инстро .fsub_pair: fld tbyte[edi] ;левый параметр fsubrp ;левый - правый jmp .fsub_store ;... это первый fpu-метод, (по)тому так много комментариев ... .fsub_nok: stc ;не вышло ret 0 ; form1: +v2 ; form2: v1+v2 .fadd: cmp ebx,1 jne .fadd_nok cmp eax,ebx ja .fadd_nok lea edi,[edi+11] mov al,2 stosb fld tbyte[ecx+11+1] je .fadd_pair .fadd_store: fstp tbyte[edi] add edi,10 ret 0 .fadd_pair: fld tbyte[edi] faddp jmp .fadd_store .fadd_nok: stc ret 0 ; form: v1/v2 .fdiv: cmp ebx,1 jne .fdiv_nok cmp eax,ebx jne .fdiv_nok add edi,11+1 xor eax,eax cmp [ecx+11+1],eax jnz .fdiv_divisor_nz cmp [ecx+11+1+4],eax jnz .fdiv_divisor_nz stosd stosd stosw ret 0 .fdiv_divisor_nz: fld tbyte[edi] fld tbyte[ecx+11+1] fdivp fstp tbyte[edi] add edi,10 ret 0 .fdiv_nok: stc ret 0 ; form: v1*v2 .fmul: cmp ebx,1 jne .fmul_nok cmp eax,ebx jne .fmul_nok add edi,11+1 fld tbyte[edi] fld tbyte[ecx+11+1] fmulp fstp tbyte[edi] add edi,10 ret 0 .fmul_nok: stc ret 0 ; form1: fld2pi ; form2: 2pi .fld2pi:fldpi fldpi faddp .store_fpu_constant: mov al,2 stosb fstp tbyte[edi] add edi,10 ret 0 ; form1: fldpi ; form2: pi .fldpi: fldpi jmp .store_fpu_constant ; form1: fldl2t ; form2: l2t .fldl2t:fldl2t jmp .store_fpu_constant ; form1: fldlg2 ; form2: lg2 .fldlg2:fldlg2 jmp .store_fpu_constant ;form: lb v .flb: fld1 jmp .flbld ;form: ld v .fld: fldlg2 .flbld: cmp ebx,1 jne .flbld_nok cmp eax,ebx jnc .flbld_nok mov edi,ecx mov al,2 stosb fld tbyte[ecx+11+1] fabs fyl2x fstp tbyte[edi] add edi,10 ret 0 .flbld_nok: stc ret 0 Пример подключения таких методов через макро: Код (Text): ... \;fpu 'fld2pi' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ '2pi' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ 'pi2' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ 'pipi' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ 'fldpi' ,.fldpi ,0 + 'f' shl 8 + $8000'0000 ,\ 'pi' ,.fldpi ,0 + 'f' shl 8 + $8000'0000 ,\ 'fldl2t' ,.fldl2t ,0 + 'f' shl 8 + $8000'0000 ,\ 'l2t' ,.fldl2t ,0 + 'f' shl 8 + $8000'0000 ,\ 'fldlg2' ,.fldlg2 ,0 + 'f' shl 8 + $8000'0000 ,\ 'lg2' ,.fldlg2 ,0 + 'f' shl 8 + $8000'0000 ,\ \ '-' ,.fsub ,0 + 'f' shl 8 ,\ '+' ,.fadd ,0 + 'f' shl 8 ,\ 'lb' ,.flb ,0 + 'f' shl 8 ,\ 'ld' ,.fld ,0 + 'f' shl 8 ,\ \ '/' ,.fdiv ,1 + 'f' shl 8 ,\ '*' ,.fmul ,1 + 'f' shl 8 ,\ \ '~' ,.fsub ,5 + 'f' shl 8 ,\ 'neg' ,.fsub ,5 + 'f' shl 8 ... Прошу(просить легко, но все же) администрацию информировать через почту при получений сообщений в личку. Если вы как-то хотите изменить calc, свяжитесь со мной для получения логина и пароля под ссылку выше(письма на rambler.ru прошу не изменять и от моего имении не отсылать). Спасибо. ...вас тоже с новым; сидел без инета ред.: манюнька ошибка была(при подлаживании строки нолями метка .raw на выходе в cl ложила ch, нужно movzx ecx,ch) - обновил.
Доброй ночи. Вот так сейчас оно выглядит. На картинке украинский. Изменить язык можно константой LANG, что в самом начале "calc.asm". Покамись их три: ENU, RUS, UKR. Помогите с языками. Привожу огрызок методов: Код (Text): \;fpu 'fld2pi' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ '2pi' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ 'pi2' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ 'pipi' ,.fld2pi ,0 + 'f' shl 8 + $8000'0000 ,\ 'fldl2t' ,.fldl2t ,0 + 'f' shl 8 + $8000'0000 ,\ 'l2t' ,.fldl2t ,0 + 'f' shl 8 + $8000'0000 ,\ 'fldlg2' ,.fldlg2 ,0 + 'f' shl 8 + $8000'0000 ,\ 'lg2' ,.fldlg2 ,0 + 'f' shl 8 + $8000'0000 ,\ 'fldpi' ,.fldpi ,0 + 'f' shl 8 + $8000'0000 ,\ 'pi' ,.fldpi ,0 + 'f' shl 8 + $8000'0000 ,\ \ '-' ,.fsub ,0 + 'f' shl 8 ,\ '+' ,.fadd ,0 + 'f' shl 8 ,\ \ '/' ,.fdiv ,1 + 'f' shl 8 ,\ '*' ,.fmul ,1 + 'f' shl 8 ,\ \ 'fabs' ,.fabs ,5 + 'f' shl 8 ,\ 'abs' ,.fabs ,5 + 'f' shl 8 ,\ 'fcos' ,.fcos ,4 + 'f' shl 8 ,\ 'cos' ,.fcos ,4 + 'f' shl 8 ,\ 'fsin' ,.fsin ,4 + 'f' shl 8 ,\ 'sin' ,.fsin ,4 + 'f' shl 8 ,\ 'fsqrt' ,.fsqrt ,4 + 'f' shl 8 ,\ 'sqrt' ,.fsqrt ,4 + 'f' shl 8 ,\ 'sr' ,.fsqrt ,4 + 'f' shl 8 ,\ 'hyp' ,.fhyp ,4 + 'f' shl 8 ,\ 'lb' ,.flb ,4 + 'f' shl 8 ,\ 'ld' ,.fld ,4 + 'f' shl 8 ,\ 'log' ,.flog ,4 + 'f' shl 8 ,\ 'power' ,.fpower ,4 + 'f' shl 8 ,\ 'pow' ,.fpower ,4 + 'f' shl 8 ,\ '**' ,.fpower ,4 + 'f' shl 8 ,\ '^' ,.fpower ,4 + 'f' shl 8 ,\ \ '~' ,.fsub ,5 + 'f' shl 8 ,\ 'neg' ,.fsub ,5 + 'f' shl 8
Добрый вечер. Дописал недостающий комментарий, добавилось пару операторов, оформил также библиотекой. Пример вызова: Код (Text): format pe gui 4.0 include 'win32ax.inc' section '' code executable import readable writable library kernel32,'kernel32.dll',\ user32,'user32.dll',\ calc.dll,'..\calc\dll\calc.dll' import calc.dll,\ calc,'calc',\ get_equates,'get_equates' include 'api\kernel32.inc' include 'api\user32.inc' entry $ invoke GetTickCount mov esi,eax ; mov ecx,1'000 ; @@: invoke calc,text,temp,<invoke get_equates>,0,0+"'",0+'dec',not 'q' ; loop @b invoke GetTickCount sub eax,esi ; hlt cinvoke wsprintf,lpOut,lpFmt,text,eax,ebx invoke MessageBoxA,0,lpOut,0,0 invoke ExitProcess,0 lpFmt db '"%s"',13,10,'-> %u ms ->',13,10,'"%s"',0 text db '< (((((((((((((((((((((((((((((2^2^3)))))))))))))))))))))))))))))',0 temp rb ($-text)*11 +1 lpOut rb MAX_PATH Ну и курсовик на 5 сдал(восьмой зачет). Спасибо за вдохновение. Удачи. Мы кажись все. Сорс по той же ссылке.
Здарова. Добавил подробное описание + косметические изменения. Покамись два языка: английский и украинский. -Почему и не на русском? -Не знаю, не знаю, не вините. Спасибо. / Сессия кончилась и гуляю до 31'го января. http://fasmme.googlecode.com/files/calc.rar Код (Text): enu: calc - a tiny calculator, based on equates ----- ideas ----- - fasm's built-in calculator by Tomasz Grysztar - Total Calculator by logosman - calculator by code_grinder - calculator(Чиста Калькулятор) by avtlab - calculator by MS ---------- written in ---------- fasm --------- main file --------- calc.inc depends on an include: 'macro\proc32.inc' --------- main proc --------- calc in the main file start from there if you are a developper ------- machine ------- 32bits or compatible, with fpu(if used) and mmx(if used) ------------- optional dirs ------------- - dll, Windows dynamic link library with main function and relatives exported - exe, Windows executable using calc.inc set LANG constant there in a source if required --------- feed back --------- edemko@rambler.ru --------- operators --------- Operators of MMX. MMX support so that required. The program must be in a QWord mode. Priority: 0. Notation: v op v. Detailed info about a one can be found at Intel and AMD docs. Here they are: movd, movq, packssdw, packsswb, packuswb, paddb ,paddd, paddsb, paddsw, paddusb, paddusw, paddw, pand, pandn, pcmpeqb, pcmpeqd ,pcmpeqw, pcmpgtb, pcmpgtd, pcmpgtw, pmaddwd, pmulhw, pmullw, por, pslld, psllq, psllw, psrld, psrlq, psrlw, psubb, psubd, psubsb, psubsw, psubusb, psubusw, psubw, punpckhbw, punpckhdq, punpckhwd, punpcklbw, punpckldq, punpcklwd, pxor. | | | priority-----operator------possible notations------explanation | + aliases| 'op' means operator| | | 'v' means value | QWord-mode operators. 0------------------------------------------------------------- | + | v op v | adds two values | | op v | | | | | - | v op v | subtracts two values or | | op v | negates a value(subtracts it from zero) | | | | bsf | op v | searches for a 1st bit=1 starting from the right, counts from 1,2... | bsl | | | | | | bsr | op v | searches for a 1st bit=1 starting from the left, counts from 1,2... | | | | byte | op v | fails if a value not in $00..$ff | | | | sbyte | op v | fails if a value not in -$80..+$7f | | | | word | op v | fails if a value not in $0000..$ffff | | | | sword | op v | fails if a value not in -$8000..+$7fff | | | | dword | op v | fails if a value not in $0000'0000..$ffff'ffff | | | | sdword | op v | fails if a value not in -$8000'0000..+$7fff'ffff 1------------------------------------------------------------- | * | v op v | gets unsigned product in edx:ecx:ebx:eax, returns ebx:eax | | | | ** | v op v | gets unsigned product in edx:ecx:ebx:eax, returns ecx:ebx | | | | *** | v op v | gets unsigned product in edx:ecx:ebx:eax, returns edx:ecx | | | | / | v op v | divides unsigned | div | | 2------------------------------------------------------------- | % | v op v | returns unsigned division's remainder | mod | | 3------------------------------------------------------------- | & | v op v | bitwise AND of two values | and | | | | | | | | v op v | bitwise OR of two values | or | | | | | | ^ | v op v | bitwise EXCLUSIVE OR of two values | xor | | 4------------------------------------------------------------- | rolb | v op v | rotates byte, 7 bits of rotate counter used only | | | | rolw | v op v | rotates word, 15 bits of rotate counter used only | | | | rold | v op v | rotates dword, 31 bits of rotate counter used only | | | | rorb | v op v | rotates byte, 7 bits of rotate counter used only | | | | rorw | v op v | rotates word, 15 bits of rotate counter used only | | | | rord | v op v | rotates dword, 31 bits of rotate counter used only | | | | rolq | v op v | rotates qword, 63 bits of rotate counter used only | | | | rorq | v op v | rotates qword, 63 bits of rotate counter used only | | | | >>> | v op v | shifts arithmetically right, 63 bits of counter used only | sar | | | | | | << | v op v | shifts left, 63 bits of counter used only | shl | | | | | | >> | v op v | shifts right, 63 bits of counter used only | shr | | | | | | shld | op v v v | equals shld of a 32bit machine | | | | shrd | op v v v | equals shrd of a 32bit machine | | | | shlq | op v v v | equals shld of a 64bit machine | | | | shrq | op v v v | equals shrd of a 64bit machine 5------------------------------------------------------------- | ~ | op v | negates a value | neg | | | | | | ! | op v | invert bits | not | | | | | | 1/ | op v | count unnormalized reciprocal, 0 returned for 0, 1 for 1 | rcp | | normalize a number to replace div with fast mul: 65'535 *** rcp 10 etc TByte-mode operators. FPU required. 0------------------------------------------------------------- | e | op | put e(2.71...) | | | | l2e | op | put log(2;e) | | | | l2t | op | put log(2;10) | | | | le2 | op | put log(e;2) | | | | let | op | put log(e;10) | | | | lt2 | op | put log(10;2) | | | | lte | op | put log(10;e) | | | | pi | op | put 3.14... | | | | pipi | op | put double pi | | | | sr2 | op | put square root of 2 | | | | srpi | op | put square root of pi | | | | + | v op v | add values | | op v | | | | | - | v op v | subtract values | | op v | 1------------------------------------------------------------- | * | v op v | multiply values | | | | / | v op v | divide values 4------------------------------------------------------------- | cotan | op v | compute co-tangent of radians | ctg | | | | | | deg | op v | radians to degrees | | | | fabs | op v | absolute value | abs | | | | | | fcos | op v | compute cosine of radians | cos | | | | | | fsin | op v | compute sine of radians | sin | | | | | | fsqrt | op v | compute square root = v^(1/2) | sqrt | | | sr | | | | | | hyp | op v v | compute hypotenuse of two legs | | | | int | op v | chop fraction leaving integral | | | | lb | op v | equals log(2 v), log 2 v, etc ;log is slower | | | | ld | op v | = log 10 v ;log is slower | | | | ln | op v | = log e v ;log is slower | | | | leg | op v v | get leg from a hypotenuse and known leg | | | | log | op v v | compute logarithm of an arbitrary base | | | | power | v op v | raise a value to some power | pow | | | ** | | | ^ | | | | | | rad | op v | degrees to radians | | | | tan | op v | compute tangent of radians | tg | | 5------------------------------------------------------------- | ~ | v op v | subtract values | neg | op v | -------------------------------------------------------------- ----------- recognition ----------- Blanks(TAB, LF, CR, SPACE) ignored. This allowes writing v op v, v op v, etc expressions, and vopv as well. Why? Do not we use 2-1, 1+1 etc forms, the answer is. Braces () stored as is, numbers put in a qword or a tbyte form, depending on the mode. Remember that mmx-operators allowed in qword mode and mmx support required. In an fpu mode numbers stored as ten byte sequences. Binary, decimal, hexadecimal, string form of numbers supported. Fpu mode adds exponential one. Binary numbers must end with b or B, decimal may end with nothing or d or D, hexadecimal must be preceded with 0x or 0X or $. String numbers must start with " or '. Every "" or '' depending on how a string was started will be witten as " or ' respectively. Of course, simple "" or '' means zero. But """hi" or 'hi''' equal '"hi' and "hi'" respectively. If ' is inside a non-string number, it's ignored proving number readability for your sake. So 0'b or 00''b or 0'000' mean zero. A 0b', 0d' etc case will raise an error as a string expected, but 0', 0x00' etc not. Exponential numbers additionally may have a fraction(after , or .) and 10's power(after e or E). They, if you really want, can end with d or D too. , or . means zero. Examples of numbers: 0b, 0B, 0, 0d, 0D, 0x0, 0X0, $0, ,, ., 0.d, .D'e +- 1, 1.024'048'e-+-1D, 'string', "string", '1''34', "1""34", '', "". Use bin or hex or string form to represent floats as is. Integer floats of a qword range stored exactly too, this also applies some unique numbers like powers of two. Operators, though, will be found first: operator - number - operator... After a one picked, a longer one can substitute it only. Exempli gratia shld can substitute shl an so on. Normally case of symbols ignored and ShL with shL treated same. --------- execution --------- After operators, braces, values got, an execution stage starts. It calculates block a block skipping any empty ones () ()() etc. For a (((()))) case queueing looks the way: (4th(3rd(2nd(1st)))). For a (()(())) case queueing looks the way: (4th(1st)(3rd(2nd))). Current operators set always expect a value to be passed to it. Thus (+) or alike raise an error as there are no params, still the block must be counted. Numbers like (number1(number2)) etc will be just unbraced into number1number2. Default method/operator execution is > id est left to the right. Putting < or > as a first byte of text overrides the setting. Hence: 1 shl 2 shl 3 -> (1 shl 2) shl 3 -> 4 shl 3 -> 32. But : <1 shl 2 shl 3 -> 1 shl (2 shl 3) -> 1 shl 16 -> 65'536. It also results into --1 etc disallowance(only bigger priority executed first) and < --1 acceptance(bigger and equal priorities). This makes putting same operations ander different names and priorities. sr2 puts square root of 2. But there is a command sr, and you can write sr2.1. In this case it will be decoded as sr2 .1. So write sqrt2.1 or sr 2.1 etc. This is because of the fact operators searched first. ukr: calc - крихітний модульний калькулятор ---- ідеї ---- - fasm'мів вбудований калькулятор від Tomasz Grysztar - Total Calculator від logosman - calculator від code_grinder - calculator(Чиста Калькулятор) від avtlab - calculator від MS ------- компило ------- фасм ------------- головний файл ------------- calc.inc передувати має include: 'macro\proc32.inc' ----------------- головна процедура ----------------- calc, що в головному файлі, якщо цікаві подробиці розробки ------ машина ------ 32біт чи сумісна, fpu(якщо вик.) та mmx(якщо вик.) ---------------- що то за папки ? ---------------- - dll, бібліотека Віндоз з експортованою головною функцією та деякими корисними - exe, програма, демонструюча роботу calc.inc виставіть константу LANG під вашу мову ------ звязок ------ edemko@rambler.ru --------- оператори --------- Оператори MMX. MMX підтримка відтак потрібна. Програма має перебувати в режимі QWord. Пріоритет для всіх: 0. Запис для всіх: v op v. Доки Intel та AMD проведуть тебе тернистими стежками. Ось вони: movd, movq, packssdw, packsswb, packuswb, paddb ,paddd, paddsb, paddsw, paddusb, paddusw, paddw, pand, pandn, pcmpeqb, pcmpeqd ,pcmpeqw, pcmpgtb, pcmpgtd, pcmpgtw, pmaddwd, pmulhw, pmullw, por, pslld, psllq, psllw, psrld, psrlq, psrlw, psubb, psubd, psubsb, psubsw, psubusb, psubusw, psubw, punpckhbw, punpckhdq, punpckhwd, punpcklbw, punpckldq, punpcklwd, pxor. | | | ранг---------оператор------форми запису------------тлумачення- | + прото | 'op' = оператор | | | 'v' = вираз/число | QWord-оператори. 0------------------------------------------------------------- | + | v op v | додати два числа | | op v | | | | | - | v op v | відняти два числа | | op v | | | | | bsf | op v | пошук першого ненульового правого біта, рахунок з одиниці | bsl | | | | | | bsr | op v | пошук першого ненульового лівого біта, рахунок з одиниці | | | | byte | op v | вдостовіритись, що число в межах $00..$ff | | | | sbyte | op v | вдостовіритись, що число в межах -$80..+$7f | | | | word | op v | вдостовіритись, що число в межах $0000..$ffff | | | | sword | op v | вдостовіритись, що число в межах -$8000..+$7fff | | | | dword | op v | вдостовіритись, що число в межах $0000'0000..$ffff'ffff | | | | sdword | op v | вдостовіритись, що число в межах -$8000'0000..+$7fff'ffff 1------------------------------------------------------------- | * | v op v | добуток в edx:ecx:ebx:eax, повернути ж ebx:eax | | | | ** | v op v | добуток в edx:ecx:ebx:eax, повернути ж ecx:ebx | | | | *** | v op v | добуток в edx:ecx:ebx:eax, повернути ж edx:ecx | | | | / | v op v | беззнакове ділення | div | | 2------------------------------------------------------------- | % | v op v | залишок беззнакового ділення | mod | | 3------------------------------------------------------------- | & | v op v | побітове множення | and | | | | | | | | v op v | побітове І | or | | | | | | ^ | v op v | побітове ВИКЛЮЧЕННЯ | xor | | 4------------------------------------------------------------- | rolb | v op v | кручення, задіяно 7 біт лічильника | | | | rolw | v op v | кручення, задіяно 15 біт лічильника | | | | rold | v op v | кручення, задіяно 31 біт лічильника | | | | rorb | v op v | кручення, задіяно 7 біт лічильника | | | | rorw | v op v | кручення, задіяно 15 біт лічильника | | | | rord | v op v | кручення, задіяно 31 біт лічильника | | | | rolq | v op v | кручення, задіяно 63 біт лічильника | | | | rorq | v op v | кручення, задіяно 63 біт лічильника | | | | >>> | v op v | знаковий здвиг в право, задіяно 63 біт лічильника | sar | | | | | | << | v op v | здвиг в ліво, задіяно 63 біт лічильника | shl | | | | | | >> | v op v | здвиг в право, задіяно 63 біт лічильника | shr | | | | | | shld | op v v v | = shld 32бітної машини | | | | shrd | op v v v | = shrd 32бітної машини | | | | shlq | op v v v | = shld 64бітної машини | | | | shrq | op v v v | = shrd 64бітної машини 5------------------------------------------------------------- | ~ | op v | відняти число від нуля | neg | | | | | | ! | op v | інверсія біт | not | | | | | | 1/ | op v | отримати 1/дільник, 0 для 0, 1 для 1 | rcp | | нормалізуйте число для заміни повільного div швидшим mul: 65'535 *** rcp 10 тощо TByte-оператори. Здається завжди, використовується fpu. 0------------------------------------------------------------- | e | op | вписати e(2.71...) | | | | l2e | op | вписати log(2;e) | | | | l2t | op | вписати log(2;10) | | | | le2 | op | вписати log(e;2) | | | | let | op | вписати log(e;10) | | | | lt2 | op | вписати log(10;2) | | | | lte | op | вписати log(10;e) | | | | pi | op | вписати 3.14... | | | | pipi | op | вписати double pi | | | | sr2 | op | вписати корінь квадратний 2 | | | | srpi | op | вписати корінь квадратний пі | | | | + | v op v | додавання | | op v | | | | | - | v op v | віднімання(змінити знак і додати) | | op v | 1------------------------------------------------------------- | * | v op v | множення | | | | / | v op v | ділення 4------------------------------------------------------------- | cotan | op v | котангенс радіан | ctg | | | | | | deg | op v | радіани в градуси | | | | fabs | op v | модуль(абс. знач.) | abs | | | | | | fcos | op v | косинус радіан | cos | | | | | | fsin | op v | синус радіан | sin | | | | | | fsqrt | op v | корінь квадратний = v^(1/2) | sqrt | | | sr | | | | | | hyp | op v v | гіпотенуза за двома катетами | | | | int | op v | відкинути дріб, вернути ціле | | | | lb | op v | = log(2 v), log 2 v, тощо ;log повільніший | | | | ld | op v | = log 10 v ;log повільніший | | | | ln | op v | = log e v ;log повільніший | | | | leg | op v v | катет за гіпотенузою та відомим катетом | | | | log | op v v | логарифм за дов. базою | | | | power | v op v | в степінь | pow | | | ** | | | ^ | | | | | | rad | op v | градуси в радіани | | | | tan | op v | тангенс радіан | tg | | 5------------------------------------------------------------- | ~ | v op v | віднімання | neg | op v | -------------------------------------------------------------- ------------- розпізнавання ------------- Пустоти(TAB=забій, LF=обрив лінії, CR=повернення каретки, SPACE=пробіл) ігноруються. Звідси v op v, v op v, vopv тощо однакові. Чому? Чи не пишемо 2-1, 1+1,.. ? Дужки () сприймаються як є, числа зчитуються в qword чи tbyte форму залежно від режиму. Памятай, що mmx-оператори дозволені в qword-режимі і mmx-підтримка очікується. В fpu-режимі числа зберігаються як послідовності з десяти байт. Двійкова, десяткова, шістнадцяткова, строкова форми чисел дозволені. Fpu-режим додатково підтримує експоненціальну. Двійкові числа мають завершуватись на b чи B, десяткові на d чи D або ніяк, шістнадцятковим передує 0x чи 0X або $. Рядкові починай з " чи '. Кожна пара "" або '', залежно від кавички стартуючої рядок, пропишеться " чи ' відповідно. Звісно, прості "" та '' значить нуль. Але """хохо" чи 'хохо''' рівно '"хохо' та "хохо'" відповідно. ' в межах чисел ігнорується і слугує для зручності читання. Отож 0'b чи 00''b або 0'000' значить нуль. Проте 0b', 0d' тощо випадки викличуть помилку, бо очікується рядок, але 0', 0x00' тощо ні. Експоненціальні числа можуть включати дріб(після , чи .) та 10'ву степінь(після e або E). Якщо кортить, можна дописати d чи D в кінці. , та . рівно нулю. Зразки чисел: 0b, 0B, 0, 0d, 0D, 0x0, 0X0, $0, ,, ., 0.d, .D'e +- 1, 1.024'048'e-+-1D, 'рядок', "рядок", '1''34', "1""34", '', "". Використовуй двійкову, шістнадцяткову, рядкову нотації для задання дійсного числа з беззаперечною точністю. Цілі qword-числа в fpu-режимі, а також степені двійки зберігаються точно. Оператори всеж шукаються першими: оператор - число - оператор... Програма намагається підібрати найдовший оператор. Наприклад shl може змінити на shld, якщо той є. Регістр символів неважливий, тому ShL та shL вважаються однаковими. --------- виконання --------- Після розпізнавання йде виконання. Опускаючи пусті () ()() тощо, обчислюється значення кожного блоку. Чергування для (((()))) виглядає так: (4тий(3тій(2гий(1ший)))). Чергування для (()(())) виглядає так: (4тий(1ший)(3тій(2гий))). Поточний набір операторів не передбачає відсутності операндів(параметрів). Із-за цього (+) тощо викликають помилку. Числа наподобі (число1(число2)) запишуться в число1число2. За умовчуванням порядок виклику методів=операторів має такий напрямок >, тобто з ліва на право. Але < чи > на самому початку рядка змінює настройку. Звідси: 1 shl 2 shl 3 -> (1 shl 2) shl 3 -> 4 shl 3 -> 32. Хоча : <1 shl 2 shl 3 -> 1 shl (2 shl 3) -> 1 shl 16 -> 65'536. Така особливість --1 не пропустить(лише оператор більшого рангу може дістатись числа, відкинувши молодші на потім), а < --1 дозволить(щоб лівіший оператор перескочив через лівий, йому(лівішому) досить мати той же ранг). Шняга сприє появі ідентичних операторів під іншими іменами та пріоритетеми. sr2 вписує корінь 2. Але ж існує оператор sr, а ми нехай пишемо sr2.1. Вираз для програми виглядатиме як sr2 .1. Ось чому sqrt2.1 та sr 2.1 існують водночас. Нагадую, це викликано перевагою пошуку операторів перш від чисел.