Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Встроенный Ассемблер


Автор: Dimannn 27.8.2006, 01:23
Как работать со строковыми константами?
нужно что-то вроде mov eax, Space , но чтобы в eax записалось на первые четыре байта спейса, а адрес. Space  - константа.

Автор: BUGOR 27.8.2006, 07:07
По-моему только через доп. переменную - указатель.
Код

const Space = '123456';
var
lpSpace: pChar;
begin
lpSpace := pChar(Space);
asm
  mov eax, lpSpace
end;

Автор: RideX 27.8.2006, 10:49
Код

mov eax, dword ptr[szString]

Автор: Romikgy 27.8.2006, 12:40
а не через lea?????

Автор: BUGOR 27.8.2006, 16:09
Romikgy, в случае с константой нет. Если бы это была переменная типа string, тогда бы lea подошла.

Код

var
str: string;
begin
str := '11';
asm
  lea eax,str
end;

Автор: RideX 27.8.2006, 21:40
Цитата(Romikgy @  27.8.2006,  15:40 Найти цитируемый пост)
а не через lea?????

Можно по разному, вот пример:
Код

implementation

{$R *.dfm}

const
  szString: PChar = 'Hello, World!';

procedure TForm1.Button1Click(Sender: TObject);
var
  buff: PChar;
begin
  GetMem(buff, 256);
  asm
    push esi
    push edi
    lea esi,szString         // mov esi, offset szString
    mov esi,[esi]
    mov edi,buff             // lea edi,buff
                             // mov edi,[edi]
    mov ecx,5
    rep movsb
    mov byte ptr[edi],'!'
    pop edi
    pop esi
  end;
  Form1.Caption := buff;
  FreeMem(buff);
end;

end.


Здесь соответствующую строку можно заменить той, которая в комментарии.

Автор: Alexeis 27.8.2006, 22:03
С константами дело гиблое! Они хранятся в специальной области памяти. Попытка обратится к данным по адресу константы приводит к ошибке! Обратитесь к http://vingrad.ru/@Петрович он в этом деле большой специалист (по крайней мере написал оч. хорошую статью описывающую все типы строк и их отображение в памяти)

Автор: BUGOR 28.8.2006, 08:03
alexeis1, дай пожалуйста ссылку на статью.

Автор: Alexeis 28.8.2006, 09:10
http://www.sources.ru/magazine/0804/delphistr.html

Автор: RideX 28.8.2006, 16:30
Цитата(alexeis1 @  28.8.2006,  01:03 Найти цитируемый пост)
Попытка обратится к данным по адресу константы приводит к ошибке!

Вы не правы, это заблуждение, на самом деле никаких ошибок не будет!  smile 

Автор: Alexeis 28.8.2006, 16:57
RideX, кажись я понял, проблемы возникают не при чтении а при записи по адресу, константы. 
Цитата

Вот, теперь, зная как выполняются те или иные преобразования, Вы сможете всегда выбрать подходящий способ. Для тех, кто ещё не "проникся" до конца этой проблемой, приведу пример. В нем, преобразование, рекомендуемое разработчиками, приводит к "странному" поведению программы:
Код

procedure X1;
var
  s :AnsiString;
  p :PChar;
begin
  s := 'abcd';
  p  := PChar(s);
  p^ := 'X'; // <- 
  ShowMessage(s);
end;


вызывает ошибку доступа к памяти при выполнении строки, помеченной <=

Автор: RideX 28.8.2006, 17:16
Цитата(alexeis1 @  28.8.2006,  19:57 Найти цитируемый пост)
кажись я понял, проблемы возникают не при чтении а при записи по адресу, константы.

Ага, типа того.. smile Но если нужно, то можно легко изменить и константу. Вот пример, как это сделать:
Код

implementation

{$R *.dfm}

const
  szString: PChar = 'Мама мыла раму?';

procedure TForm1.Button1Click(Sender: TObject);
var
  lpProtect, nLen: DWORD;
  szOverlay: PChar;
begin
  if MessageBox(Handle, szString, 'const', MB_YESNO or MB_ICONQUESTION) = mrNo then Exit;

  szOverlay := 'Папа пил пиво...';
  nLen := Length(szString);
  asm
    lea eax, lpProtect
    push eax
    push PAGE_READWRITE
    push nLen
    push szString
    call VirtualProtect
    test eax,eax
    jz @err

    mov esi, szOverlay
    mov edi, offset szString
    mov edi,[edi]
    mov ecx,nLen
    rep movsb

    lea eax, lpProtect
    push eax
    mov eax,[eax]
    push eax
    push nLen
    push szString
    call VirtualProtect

    @err:
  end;

  MessageBox(Handle, szString, 'overlay', MB_ICONINFORMATION);
end;

end.

Автор: Dimannn 6.9.2006, 19:03
Извиняюсь за задержку, технические сложности.


Но суть проблемы в том, чтобы минимальными усилиями заставить включить строковую константу в конечный файл, но надо учесть, что после операций над ним, операция на памятью под адресом константы может вызвать ошибку.
Константа должна быть локальной и нетипизированной!

mov eax, Space и mov eax, dword ptr(Space) компилируются одинаково,
и при этом они счетают константу DWORDом(при SPACE = #10#13#15#14 получаю mov eax, 10131415)

Собственно, задача моя заключается в том, чтобы заставить компилятор сделать несколько постого места после retn процедуры, а строковые константы именно туда и пишутся.

Добавлено @ 19:10 
RideX, Собственно говоря, это можно сделать и без ассемблера.
Код

    VirtualProtect(Pointer(szString), nLen, PAGE_READWRITE, lpProtect);
    CopyMemory(Pointer(szString),Pointer(szOverlay),nLen);
    VirtualProtect(Pointer(szString), nLen, lpProtect, lpProtect);

Автор: RideX 6.9.2006, 21:48
Цитата(Dimannn @  6.9.2006,  22:03 Найти цитируемый пост)
Собственно говоря, это можно сделать и без ассемблера.
Я очень рад, думаю теперь ты с асмом на ты!


Цитата(Dimannn @  6.9.2006,  22:03 Найти цитируемый пост)
mov eax, Space и mov eax, dword ptr(Space) компилируются одинаково,
и при этом они счетают константу DWORDом(при SPACE = #10#13#15#14 получаю mov eax, 10131415)

Не может быть, только что проверил
Код

00401EB0  |. 8B45 FC           MOV EAX,DWORD PTR SS:[EBP-4]

eax = 00401F10, и по этому адресу лежит:
Код

00401F10  0A 0D 0F 0E 00 00 00 00                          ......

...что тебе и нужно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)