You are not logged in.
В Delphi есть такие замечательные функции: IntToStr, FloatToStr
function IntToStr(Value: Integer): string; // FmtStr(Result, '%d', [Value]); asm PUSH ESI MOV ESI, ESP SUB ESP, 16 XOR ECX, ECX // base: 0 for signed decimal PUSH EDX // result ptr XOR EDX, EDX // zero filled field width: 0 for no leading zeros CALL CvtInt MOV EDX, ESI POP EAX // result ptr CALL System.@LStrFromPCharLen ADD ESP, 16 POP ESI end;
Так вот есть ассмблеровский код... Хочу преобразовать его в объектный код и воткнуть между hex...end в scm...
Насколько я понимаю, входной Integer и выходной string находятся в регистре ESI... То есть мне надо сначала записать в него, а потом считать... Как это можно сделать? Допустим есть локальная переменная 1@ : Integer... 4 байта... Как в scm можно получить адрес памяти этой переменной, а потом на ассемблере записать 4 байта, начиная с этого адреса в регистр... И как записать из регистра в память игры...
Надеюсь я правильно описал суть проблемы...
Offline
Во-первых, ты изначально выбрал неправильную функцию для переноса в хекс. Поищи лучше оптимизированные варианты этой функции, ибо борландовский вариант очень громоздкий.
Во-вторых, переносить большую функцию в хекс, неразумно. Правильней было бы написать длл и использовать функцию из нее через load_dll, get_proc_address, call.
В-третьих, результат функции всегда пишется в eax. Входные параметры зависят от соглашения о вызове (stdcall, cdecl, pascal) и могут передаваться через стек или регистры.
Адрес переменной можно получить используя опкод 0A9F: 0@ = current_thread_pointer
Смотри например здесь http://sannybuilder.com/forums/viewtopi … 3742#p3742
(функция _varToOffset как раз то, что тебе нужно).
Offline
эх... вся проблема в том, что я ассемблер не знаю совсем:cry:Ладно, буду учиться делать dll-ки
Offline
Если не знаешь ассемблер, тогда тем более проще делать это через длл
Offline
так... длл есть...
library mylib; uses SysUtils, Classes; function Int2Str( Value : Integer ) : String; var Buf : array[ 0..15 ] of Char; Dst : PChar; Minus : Boolean; D: WORD; begin Dst := @Buf[ 15 ]; Dst^ := #0; Minus := False; if Value < 0 then begin Value := -Value; Minus := True; end; D := Value; repeat Dec( Dst ); Dst^ := Char( (D mod 10) + Byte( '0' ) ); D := D div 10; until D = 0; if Minus then begin Dec( Dst ); Dst^ := '-'; end; Result := Dst; end; begin end.
В СБ есть опкод, определяющий адрес процедуры
0AA4: $hPROC = get_proc_address "GetVersion" library $hLIB // IF and SET
Чтобы потом можно было вызвать ее
0AA5: call $hPROC num_params 1 pop 1 $param
А для функций такого нет... Есть только опкод
0AA7: call_function 0x569660 num_params 2 pop 2 $COORD_X $COORD_Y $GROUND
, который обращается к функции уже по найденному адресу... А как мне найти этот адрес?
Offline
в любом опкоде можно вместо числа использовать переменную
0AA7: call_function $hPROC num_params 2 pop 2 $COORD_X $COORD_Y $GROUND
странно что ты этого не знаешь
не забудь использовать локальные переменные
Offline
конешно я это знаю... я не знаю опкода, определяющего адрес функции... Или здесь тоже 0AA4 подойдет?
Offline
0AA4 работает и для процедур и для функций.
Offline
А у меня не рабоает ни для того, ни для другого...
{$cleo} 0000: repeat wait 0 until 0AA2: 0@ = load_library "CLEO\mylib.dll" // IF and SET 00BC: show_text_highpriority GXT 'MTIME3' time 1000 flag 1 // ~s~Come back between 9:00 and 17:00. //До сюда исполнение доходит repeat wait 0 until 0AA4: 1@ = get_proc_address "Int2Str" library 0@ // IF and SET //А до сюда - нет 03E5: show_text_box 'HELP101' // Respect can be earned be passing certain missions, killing rival gangs members, gaining territory and tagging. 2@ = 36 0AA7: call_function 1@ num_params 1 pop 1 2@ 31@ repeat wait 0 until 0A9A: 3@ = openfile "test.txt" mode 0x77 // IF and SET 0A9E: writefile 3@ size 8 from 31@ 0A9B: closefile 3@ 0A93: end_custom_thread
{$cleo} 0000: wait 5000 repeat wait 0 until 0AA2: 0@ = load_library "CLEO\Project2.dll" // IF and SET 00BC: show_text_highpriority GXT 'MTIME3' time 1000 flag 1 // ~s~Come back between 9:00 and 17:00. //До сюда исполнение доходит wait 5000 repeat wait 0 until 0AA4: 1@ = get_proc_address "HelloWorld" library 0@ // IF and SET //А до сюда не доходит 03E5: show_text_box 'HELP101' // Respect can be earned be passing certain missions, killing rival gangs members, gaining territory and tagging. wait 5000 0AA5: call 1@ num_params 0 pop 0 0A93: end_custom_thread
Правда, я не уверен, что длл правильно собираю...
library MyFirstDLL; uses SysUtils, Classes, Forms, Windows; procedure HelloWorld(AForm : TForm); begin MessageBox(AForm.Handle, 'Hello world!', 'DLL Message Box', MB_OK or MB_ICONEXCLAMATION); end; exports HelloWorld; begin end.
library mylib; uses SysUtils, Classes; function Int2Str( Value : Integer ) : String; var Buf : array[ 0..15 ] of Char; Dst : PChar; Minus : Boolean; D: WORD; begin Dst := @Buf[ 15 ]; Dst^ := #0; Minus := False; if Value < 0 then begin Value := -Value; Minus := True; end; D := Value; repeat Dec( Dst ); Dst^ := Char( (D mod 10) + Byte( '0' ) ); D := D div 10; until D = 0; if Minus then begin Dec( Dst ); Dst^ := '-'; end; Result := Dst; end; begin end.
Offline
В mylib забыл exports
Offline
Все, спасибо, разобрался=)
Offline
То есть грубо говоря длл - это отдельная программа, загружаемая по команде из скрипта - скрипт передает в длл какие-то исходные данные, а длл возвращает результат для продолжения работы скрипта? Правильно я понял?
Offline
dll - dynamic link library
Динамическая подключаемая библиотека... В ней находятся процедуры и функции, которые можно вызывать из любой программы
Offline