Текущий архив: 2007.02.25;
Скачать: CL | DM;
ВнизAssembler Найти похожие ветки
← →
i-am-vladko © (2007-01-28 23:36) [0]Нужно перебросить первые 2 Char`a в Result, попробовал на ASM - чето не выходит )) В ASM я далеко не спец. Подскажите, что не так :
Используюregister;
- значит @Value - в EAX, Result будет там же. @Value - 4 байта, за ним - байт длины строки, значит Value[1] [EAX - 05], Value[2] [EAX - 06]. Word - 2 байта, поэтому бросаю в BL и BH. Вот что получается но не работает ))function StrToWord(Value: string): Word; register;
asm
MOV BL, [EAX - 05]
MOV BH, [EAX - 06]
MOV EAX, EBX
end;
← →
колхоз глазами хакера (2007-01-28 23:58) [1]
function StrToWord(Value: string): Word; register;
asm
movzx ebx,word ptr [eax]
mov eax,ebx
end;
← →
колхоз глазами хакера (2007-01-29 00:00) [2]Хотя и это избыточно. movzx eax, word ptr [eax] достаточно
← →
Alex Konshin © (2007-01-29 02:09) [3]А назачем ассемблер-то?
type
PWORD = ^Word;
Result := PWORD(PChar(Value))^;
← →
Alx2 © (2007-01-29 07:31) [4]Result := word((@value)^);
← →
Alx2 © (2007-01-29 07:35) [5]Ой.. Там строка. Тогда не то написал в [4]
← →
i-am-vladko © (2007-01-29 20:40) [6]Спасибо )
movzx eax, word ptr [eax]
- работает отлично- тоже возвращает правильный результат, но выдает Exception при попытке TypeCast`a результата. В чем разница?
movzx ebx,word ptr [eax]
mov eax,ebx
← →
Palladin © (2007-01-29 21:07) [7]потому что кролики это не только ценный мех, а строка это не просто указатель
хочешь работать с указателями - используй PChar
← →
i-am-vladko © (2007-01-29 21:25) [8]Начитался "Использование ассемблера в Дельфи" - мало че понял, а хочется попробовать... Вот и мучаюсь - не судите строго )) в книге(статье? хз*) много что очень прозрачно для новичка
← →
колхоз глазами хакера (2007-01-29 22:01) [9]А чего ты добиться хочешь? Попробуй сам для себя сформулировать. ;-)
Ну и вообще-то прежде чем разбираться с "ассемблером в делфи" нужно хорошо разобраться с ассемблером как таковым...
← →
колхоз глазами хакера (2007-01-29 22:09) [10]> movzx ebx,word ptr [eax]
> mov eax,ebx
> - тоже возвращает правильный результат, но выдает Exception
> при попытке TypeCast`a результата. В чем разница?
An asm statement must preserve the EDI, ESI, ESP, EBP, and EBX registers, but can freely modify the EAX, ECX, and EDX registers.
← →
i-am-vladko © (2007-01-29 22:12) [11]
> Ну и вообще-то прежде чем разбираться с "ассемблером в делфи"
> нужно хорошо разобраться с ассемблером как таковым...
полностью согласен
как по мне - "чистый" ASM - жуткая вещь.
Не один раз пробовал... все вроде правильно а ничего не работает - типичный недостаток знаний
← →
i-am-vladko © (2007-01-29 22:17) [12]
> колхоз глазами хакера (29.01.07 22:09) [10]
Использование ассемблера в Дельфи :
> Если вы изменяете, другие регистры общего назначения (EBX,
> ESI, EDI), то вы обязаны восстановить их первоначальное
> состояние до выхода из процедуры
- нашел
← →
i-am-vladko © (2007-01-30 11:50) [13]а что здесь не так?
обратная функция - нужно Value перебросить в первые 2 байта, и установить длину строки в 2.
EBX уже сохраняю ))function WordToStr(Value: word): string; register;
asm
push ebx
mov ebx, eax
call System.@NewAnsiString
mov edx, eax
mov [edx],$00000002
MOV [EDX - 4], BX
mov eax, edx
pop ebx
end;
← →
Сергей М. © (2007-01-30 12:09) [14]
> что здесь не так?
Все не так.
Вот цитата из "генофонда":
{ -> EAX length }
{ <- EAX pointer to new string }
А у тебя что в eax содержится при вызове NewAnsiString ? Все что угодно (точнее - произволтное значение параметра Value), только не длина будущей строки.
← →
i-am-vladko © (2007-01-30 12:31) [15]Спасибо за замечание )
если правильно понял, нужно :function WordToStr(Value: word): string; register;
asm
push ebx
mov ebx, eax
mov eax, $00000002
call System.@NewAnsiString
mov [eax - 4], ebx
mov edx , [eax]
mov eax, edx
pop ebx
end;
и снова чето не так ((
← →
Сергей М. © (2007-01-30 13:23) [16]
function WordToStr(Value: word): String;
asm
push edx
push eax
mov eax, $00000002
call System.@NewAnsiString
pop [eax]
pop edx
mov [edx],eax
end;
← →
Сергей М. © (2007-01-30 14:18) [17]
> i-am-vladko © (30.01.07 12:31) [15]
"Засада" здесь в следующем: если ты объявил в своей ф-ции вых.параметр как LargeString, компилятор для ее вызова сгенерирует код, передающий в edx неявным параметром адрес, куда ты должен записать адрес созданной тобой в теле ф-ции длинной строки.
Т.о.. "дело" выглядит след.образом:
function WordToStr(Value: word): String; //параметр Value передается через eax по значению, спецификатор register здесь нафиг не нужен
asm
push edx //в edx передан адрес ячейки памяти, куда мы должны записать результат работы ф-ции - создание LargeString-структуры
push eax //eax нам нужен для передачи в кач-ве параметра размера создаваемой вызовом NewAnsiString строки, поэтому сохраним его ориг.значение - параметр Value (старшие его 2 байта всегда = 0)
mov eax, $00000002 //2 байта, размер того самого Value-параметра типа Word
call System.@NewAnsiString //собственно создание LargeString-структуры, edx на выходе не определен, поэтому первой строкой мы сохранили его оригинальное (нужное нам) значение
//в eax - адрес буфера LargeInt-данных, размер этого буфера всегда кратен 4
pop [eax] //на вершине стека - параметр Value, записываем его в буфер результата с выталкиванием из стека
pop edx //на вершине стека - адрес, куда мы должны записать адрес только что созданной и заполненной LargeString-структуры
mov [edx],eax
//усе !! Все корректно, можно выполнять RET
end;
← →
GrayFace © (2007-01-30 14:24) [18]i-am-vladko © (28.01.07 23:36)
Использую register; - значит @Value - в EAX, Result будет там же. @Value - 4 байта, за ним - байт длины строки, значит Value[1] [EAX - 05], Value[2] [EAX - 06]. Word - 2 байта, поэтому бросаю в BL и BH. Вот что получается но не работает ))
В eax не @Value, а Value - @Value бывает только при указании var и при указании const для статических массивов и record-ов. (не знаю, как передаются Int64)
string - это указатель на первый символ
(string - 4)^ - длина массива
(string - 8)^ - счетчик ссылок
Alex Konshin © (29.01.07 2:09) [3]
Result := PWORD(PChar(Value))^;Result := PWORD(Value)^;
i-am-vladko © (29.01.07 20:40) [6]
movzx ebx,word ptr [eax]
mov eax,ebx
- тоже возвращает правильный результат, но выдает Exception при попытке TypeCast`a результата. В чем разница?
Тут ebx портится. Правила inline asm: регистры eax, ecx, edx можно модифицировать как угодно, а ebx и пр. надо сохранять.
← →
GrayFace © (2007-01-30 14:35) [19]колхоз глазами хакера (29.01.07 22:01) [9]
Ну и вообще-то прежде чем разбираться с "ассемблером в делфи" нужно хорошо разобраться с ассемблером как таковым...
Да нет, основа едина, ее надо понимать, а остальное - только для "избранных" - тех, кто оптимизирует код на уровне Асма.
Сергей М. © (30.01.07 13:23) [16]
pop [eax]
4 байта запишется, из них 2 верхних произвольные.function WordToStr(Value: word): String;
asm
push edx
push eax
mov eax, $00000002
call System.@NewAnsiString
pop ecx
mov [eax], cx
pop edx
mov [edx],eax
end;
← →
Сергей М. © (2007-01-30 14:51) [20]
> GrayFace © (30.01.07 14:35) [19]
> 4 байта запишется, из них 2 верхних произвольные.
А по барабану.
4 реально выделено, из них первые 2 актуальны, остальное - "мусор"
← →
GrayFace © (2007-01-31 13:09) [21]Нуль-байт нужен.
← →
Сергей М. © (2007-01-31 13:15) [22]
> Нуль-байт нужен.
Он в моем примере гарантированно будет.
← →
GrayFace © (2007-01-31 13:39) [23]В функцию подается word, поэтому верхние байты eax - произвольные. 3-байт заменит собой нуль-байт.
← →
Сергей М. © (2007-01-31 14:17) [24]Покажи реальный пример, когда старшее слово eax при этом не равно нулю - и я признаю ошибку ..
← →
GrayFace © (2007-02-01 16:08) [25]
function MyFunc: Integer;
begin
Result:=$21F20000;
end;
function WordToStr(Value: word): String;
asm
push edx
push eax
mov eax, $00000002
call System.@NewAnsiString
pop [eax]
pop edx
mov [edx],eax
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyFunc;
ShowMessage(WordToStr($EEC2));
end;
← →
Сергей М. © (2007-02-01 16:23) [26]
> GrayFace © (01.02.07 16:08) [25]
Ок, замечание принято, ошибку признаю.
Коррекция для общего случая:
function WordToStr(Value: word): String;
asm
push edx
movzx eax, ax
push eax
mov eax, $00000002
call System.@NewAnsiString
pop [eax]
pop edx
mov [edx],eax
end;
Страницы: 1 вся ветка
Текущий архив: 2007.02.25;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.046 c