Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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]
- работает отлично


movzx ebx,word ptr [eax]
mov eax,ebx
- тоже возвращает правильный результат, но выдает Exception при попытке TypeCast`a результата. В чем разница?


 
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.53 MB
Время: 0.029 c
2-1170944309
olevacho_
2007-02-08 17:18
2007.02.25
проблемма с типом boolean


2-1170688380
Light-blr
2007-02-05 18:13
2007.02.25
программная перерисовка ComboBox (Style=csOwnerDrawFixed)


2-1170663952
Fs
2007-02-05 11:25
2007.02.25
Связка таблиц?


15-1170440145
_uw_
2007-02-02 21:15
2007.02.25
О Картинках


15-1170333812
xayam
2007-02-01 15:43
2007.02.25
Authorware 7