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