Вверх ↑
Этот топик читают: Гость
Ответов: 499
Рейтинг: 1
#1: 2011-01-19 04:15:04 ЛС | профиль | цитата
есть простенький код, который вычисляет некое число:

X=43'046'721

MOV EDI, X
MOV EAX, -2'093'742'815
IMUL EDI
ADD EDX, EDI

десятки миллиардов умножаются на сотни миллионов, в результате получается 64-х битное число раскиданное по двум регистрам (старшая:младшая часть), далее они суммируются и на выходе уже имеется обычное 32-х битное.

должна получиться пара чисел -20'984'738 : 622'068'833, но обычными средствами Hiasm-а можно получить только младшую часть. порядок цифр меня немного смущает, с какого боку можно подступиться, посдкажите?
карма: 0

0
Ответов: 8928
Рейтинг: 823
#2: 2011-01-19 09:29:06 ЛС | профиль | цитата
HikeR, средствами HiAsm-а (как и любого языка) можно выполнять математику любой разрядности, если представить числа в виде текста и производить поразрядное сложение-вычитание
------------ Дoбавленo в 09.29:
Например, так (работает только сложение, остальное сами):

Add(MainForm,2953706,196,28)
{
Height=108
}
Add(Edit,14282128,392,35)
{
Width=392
Align=2
Ctl3D=1
Text="123456789098765432101234567890987654321"
}
Add(Edit,2294439,196,91)
{
Left=165
Top=45
Align=2
Color=-16777201
Enabled=1
Ctl3D=1
WinStyle=1
Text=""
ReadOnly=0
}
Add(Edit,5357195,343,35)
{
Top=40
Width=392
Align=2
Ctl3D=1
Text="123456789098765432101234567890987654321"
}
Add(ComboBox,8873892,252,28)
{
Top=20
Height=21
Strings=#1:+|1:-|1:*|1:/|1:^|
Point(Index)
Point(doSelect)
link(onClick,2876633:doValue,[])
}
Add(Button,15668046,252,91)
{
Top=60
Width=30
Caption="="
link(onClick,15774288:doData,[])
}
Add(Label,9813515,392,91)
{
Left=30
Top=60
Width=4
Height=4
Font=[MS Sans Serif,10,1,0,1]
Caption=""
}
Add(DoData,15774288,294,91)
{
link(onEventData,10445877:doWork1,[])
link(Data,2876633:Value,[])
}
Add(MultiElement,10445877,343,91)
{
link(onEvent1,9813515:doText,[])
link(Data1,5357195:Text,[])
link(Data2,14282128:Text,[(356,79)(398,79)])
}
BEGIN_SDK
Add(EditMulti,10215565,21,21)
{
EventCount=1
WorkCount=1
DataCount=2
Width=160
Height=305
VOffset=28
HOffset=70
link(doWork1,1069882:doEvent,[])
}
Add(MultiElement,6626599,119,49)
{
@Hint=#5:A + B|
link(onEvent1,16074073:doWork2,[])
link(Data1,2417068:Var3,[(125,40)])
link(Data2,15691483:Var3,[(132,33)])
}
BEGIN_SDK
Add(EditMulti,9882715,21,21)
{
EventCount=1
WorkCount=1
DataCount=2
VarCount=1
Width=615
Height=249
VOffset=21
HOffset=20
link(doWork1,6830470:doLength,[])
link(Var1,10511226:Value,[(47,260)(580,260)])
}
Add(Length,6830470,105,42)
{
link(onLength,12104267:doLength,[])
link(Str,11573257:Var3,[(111,33)])
}
Add(Length,12104267,154,42)
{
link(onLength,6243621:doOperation,[])
link(Str,6866631:Var3,[(160,30)])
}
Add(If_else,15432866,476,140)
{
Type=5
Op2=Integer(0)
link(onTrue,6921513:doValue,[])
link(onFalse,6921513:doClear,[])
}
Add(Math,6243621,203,42)
{
OpType=39
link(onResult,15040536:doFor,[(247,48)(247,94)(45,94)(45,125)])
link(Op1,6830470:Result,[(209,30)(194,30)(194,80)(111,80)])
}
Add(For,15040536,56,119)
{
Start=1
link(onEvent,6867146:doCopy,[])
link(onStop,4237188:doEvent1,[(98,132)(98,188)])
link(End,6243621:Result,[(69,89)(69,89)(209,89)])
}
Add(Copy,6867146,105,119)
{
Count=1
Direction=1
link(onCopy,3923967:doCompare,[])
link(Str,11573257:Var2,[(111,109)(83,109)])
}
Add(Copy,14965547,231,119)
{
Count=1
Direction=1
link(onCopy,14907901:doCompare,[])
link(Str,6866631:Var2,[(237,99)(146,99)])
link(Position,15040536:Position,[(244,107)(228,107)(228,166)(62,166)])
}
Add(GetDataEx,11573257,77,28)
{
Angle=3
link(Data,9882715:Data1,[(47,33)])
}
Add(Memory,9036196,189,119)
{
Default=Integer(0)
link(onData,14965547:doCopy,[])
}
Add(If_else,3923967,147,119)
{
Type=5
Op2=String()
link(onTrue,9036196:doValue,[])
link(onFalse,9036196:doClear,[])
}
Add(Memory,4389167,315,119)
{
Default=Integer(0)
link(onData,9847439:doCalc,[])
}
Add(If_else,14907901,273,119)
{
Type=5
Op2=String()
link(onTrue,4389167:doValue,[])
link(onFalse,4389167:doClear,[])
}
Add(GetDataEx,6866631,140,25)
{
Angle=3
link(Data,9882715:Data2,[(54,30)])
}
Add(MathParse,9847439,364,119)
{
DataCount=3
MathStr="%1 + %2 + %3"
link(onResult,14461451:doEvent1,[])
link(X2,9036196:Value,[(377,109)(355,109)(355,159)(195,159)])
link(X3,5769567:Result,[(384,107)(401,107)(401,178)(440,178)])
}
Add(Hub,14461451,406,119)
{
link(onEvent1,9693080:doOperation,[(427,125)(427,104)])
link(onEvent2,5769567:doOperation,[(427,132)(427,146)])
}
Add(Math,9693080,434,98)
{
OpType=8
Op2=10
ResultType=0
link(onResult,9912733:doWork2,[])
}
Add(Math,5769567,434,140)
{
OpType=7
Op2=10
ResultType=0
link(onResult,15432866:doCompare,[])
}
Add(StrCat,8462730,574,98)
{
Point(doClear)
link(Str2,6885741:Var3,[(587,86)(614,86)(614,141)])
}
Add(Hub,4237188,490,182)
{
OutCount=3
link(onEvent1,11546678:doData,[])
link(onEvent2,10511226:doValue,[(521,195)(521,223)])
link(onEvent3,8462730:doClear,[(514,202)(514,111)])
}
Add(Memory,6921513,525,140)
{
Default=String()
}
Add(DoData,11546678,525,182)
{
link(onEventData,9912733:doWork3,[(564,188)])
link(Data,6921513:Value,[])
}
Add(HubEx,9912733,560,98)
{
link(onEvent,8462730:doStrCat,[])
}
Add(GetDataEx,6885741,574,136)
{
link(Data,8462730:Result,[])
}
Add(Memory,10511226,574,217)
{
Point(Data)
link(onData,9882715:onEvent1,[(620,223)(620,47)])
link(Data,6885741:Var2,[])
}
END_SDK
Add(MultiElement,266921,119,161)
{
link(onEvent1,1398670:doWork2,[])
link(Data1,9806193:Var3,[(125,152)])
link(Data2,13462533:Var3,[(132,145)])
}
BEGIN_SDK
Add(EditMulti,9882715,21,21)
{
EventCount=1
WorkCount=1
DataCount=2
VOffset=20
HOffset=20
}
END_SDK
Add(MultiElement,200527,119,217)
{
link(onEvent1,4257832:doWork2,[])
link(Data1,12288313:Var3,[(125,208)])
link(Data2,4062197:Var3,[(132,201)])
}
BEGIN_SDK
Add(EditMulti,9882715,21,21)
{
EventCount=1
WorkCount=1
DataCount=2
VOffset=20
HOffset=20
}
END_SDK
Add(MultiElement,5021610,119,266)
{
link(onEvent1,4257832:doWork3,[(172,272)])
link(Data1,12288313:Var2,[(125,259)(97,259)])
link(Data2,4062197:Var2,[(132,254)(104,254)])
}
BEGIN_SDK
Add(EditMulti,9882715,21,21)
{
EventCount=1
WorkCount=1
DataCount=2
VOffset=20
HOffset=20
}
END_SDK
Add(GetDataEx,12288313,91,203)
{
link(Data,9806193:Var2,[])
}
Add(GetDataEx,4062197,98,196)
{
link(Data,13462533:Var2,[])
}
Add(GetDataEx,9806193,91,147)
{
link(Data,5946521:Var2,[])
}
Add(GetDataEx,13462533,98,140)
{
link(Data,5630468:Var2,[])
}
Add(GetDataEx,5946521,91,91)
{
link(Data,2417068:Var2,[])
}
Add(GetDataEx,5630468,98,84)
{
link(Data,15691483:Var2,[])
}
Add(GetDataEx,2417068,91,35)
{
link(Data,10215565:Data1,[])
}
Add(GetDataEx,15691483,98,28)
{
link(Data,10215565:Data2,[])
}
Add(IndexToChanel,1069882,35,49)
{
Count=5
link(onEvent1,6626599:doWork1,[])
link(onEvent2,16687405:doWork1,[(93,62)(93,111)])
link(onEvent3,266921:doWork1,[(89,69)(89,167)])
link(onEvent4,200527:doWork1,[(83,76)(83,223)])
link(onEvent5,5021610:doWork1,[(76,83)(76,272)])
}
Add(HubEx,16074073,168,49)
{
link(onEvent,10215565:onEvent1,[])
}
Add(HubEx,14908742,168,105)
{
Angle=3
link(onEvent,16074073:doWork3,[])
}
Add(HubEx,1398670,168,161)
{
Angle=3
link(onEvent,14908742:doWork3,[])
}
Add(HubEx,4257832,168,217)
{
Angle=3
link(onEvent,1398670:doWork3,[])
}
Add(MultiElement,16687405,119,105)
{
@Hint=#5:A - B|
link(onEvent1,14908742:doWork2,[])
link(Data1,5946521:Var3,[(125,96)])
link(Data2,5630468:Var3,[(132,89)])
}
BEGIN_SDK
Add(EditMulti,9882715,21,21)
{
EventCount=1
WorkCount=1
DataCount=2
VarCount=1
Width=699
Height=249
VOffset=21
HOffset=20
}
END_SDK
END_SDK
Add(Memory,2876633,294,35)
{
Default=Integer(0)
}

карма: 19

0
Ответов: 16884
Рейтинг: 1239
#3: 2011-01-19 12:50:13 ЛС | профиль | цитата
IC в помощь
code_22232.txt
и здесь посмотри Ф.Меньшиков-Оллимпиадные задачи по программирыванию

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
1
файлы: 1code_22232.txt [399B] [127]
Голосовали:sаmakacd
Ответов: 1821
Рейтинг: 168
#4: 2011-01-19 12:55:55 ЛС | профиль | цитата
Tad писал(а):
IC в помощь

error
------------ Дoбавленo в 12.55:
уже нормально
карма: 5

0
Ответов: 499
Рейтинг: 1
#5: 2011-01-19 23:31:35 ЛС | профиль | цитата
Леонид, примерно такой вариант и крутился в голове, спасибо, так сказать, за готовое решение ;) вобще оказалось, что это есть "длинная математика", судя по этому источнику - http://synset.com/ru/Pascal:длинная_арифметика , даже и не знал. однако вариант со встроенным асмом оказался быстрее, у меня таких чисел много ;)

кстати, в ассемблерных вставках не нужно принудительно сохранять регистры через PUSH/POP? Tad предлагает положится на компилятор, в коде компонентов где-то есть такое, где-то нет.
карма: 0

0
Ответов: 16884
Рейтинг: 1239
#6: 2011-01-20 01:50:42 ЛС | профиль | цитата
HikeR, http://tempfile.ru/file/1623907
------------ Дoбавленo в 01.50:
HikeR писал(а):
предлагает положится на компилятор,
я не предлагаю никуда ложиться .
------------ Дoбавленo в 01.50:
Есть соглашение об использовании регистров в asm-вставках. И DELPHI и FPC их поддерживают.PUSH/POP они вставляют сами.
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 499
Рейтинг: 1
#7: 2011-01-20 02:01:47 ЛС | профиль | цитата
понятно, возня с регистрами отпадает. зато опять пара вопросов:
что такое IntNo? гугль про такой тип данных сразу не рассказывает.
квадратные скобки вокруг переменных в коде — просто для удобства восприятия или что-то еще значат? у меня итоговый вариант без скобок, пока работает:

function CalcSerial(var1:integer):integer;
var out1:integer;
begin
asm
mov edi,var1
mov eax,$83340521
imul edi
add edx,edi
sar edx,$9
mov ecx,edx
shr ecx,$1f
add ecx,edx
imul ecx,ecx,$3e7
sub edi,ecx
mov out1,edi
end;
Result:=out1;
end;


p.s.
сейчас разбираюсь в некотором алгоритме генерации и поражаюсь объему кода необходимого для эмуляции пары-тройки ассемблерных команд ;)

p.p.s.
сорри за первый вопрос, что такое IntNo уже понял.
карма: 0

0
файлы: 1code_22237.txt [308B] [82]
Ответов: 16884
Рейтинг: 1239
#8: 2011-01-20 10:00:47 ЛС | профиль | цитата
HikeR писал(а):
возня с регистрами отпадает
Не со всеми! Найди в поисковике "Assembler в Delphi".

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 499
Рейтинг: 1
#9: 2011-01-21 12:15:40 ЛС | профиль | цитата
ага, для дельфи пишут что:
В ассемблерных процедурах и функциях нужно сохранять регистры EDI, ESI, ESP, EBP, and EBX и свободно оперировать регистрами EAX, ECX, and EDX.


однако если в асмовой вставке забить на вышеприведенную цитату (не сохранять EDI, EBX...), то после FPC программа работает нормально, а дельфи, как и ожидалось, выдает исключение при запуске.

карма: 0

0
9
Сообщение
...
Прикрепленные файлы
(файлы не залиты)