سؤال

أحاول أن أتعلم برمجة التجميع المضمنة في دلفي، وتحقيقا لهذه الغاية وجدت هذا المقال مفيدة للغاية.

الآن أرغب في كتابة دالة تجميع ترجع سلسلة طويلة، على وجه التحديد AnsiString (للبساطة).لقد كتبت

function myfunc: AnsiString;
asm
  // eax = @result
  mov edx, 3
  mov ecx, 1252
  call System.@LStrSetLength
  mov [eax + 0], ord('A')
  mov [eax + 1], ord('B')
  mov [eax + 2], ord('C')
end;

توضيح:

الدالة التي تُرجع سلسلة لها قيمة غير مرئية var result: AnsiString (في هذه الحالة) المعلمة، لذلك، في بداية الوظيفة، eax يجب أن يحمل عنوان السلسلة الناتجة.ثم قمت بتعيين edx و ecx إلى 3 و1252 على التوالي، ثم اتصل System._LStrSetLength.في الواقع، أنا أفعل

  _LStrSetLength(@result, 3, 1252)

حيث 3 هو الطول الجديد للسلسلة (بالأحرف = البايت) و1252 هو الطول القياسي ويندوز-1252 صفحة الرموز.

ثم معرفة ذلك eax يكون عنوان الحرف الأول من السلسلة, ، لقد قمت ببساطة بتعيين السلسلة على "ABC".لكنه لا يعمل - إنه يعطيني بيانات غير منطقية أو EAccessViolation.ما المشكلة؟

تحديث

الآن لدينا تطبيقان يعملان على ما يبدو myfunc, ، توظيف واحد NewAnsiString وتوظيف واحد LStrSetLength.لا يسعني إلا أن أتساءل عما إذا كان كلاهما صحيحًا، بمعنى أنهما لا يفسدان معالجة دلفي الداخلية للسلاسل (العد المرجعي، والتحرير التلقائي، وما إلى ذلك).

هل كانت مفيدة؟

المحلول

يجب عليك استخدام نوع من:

function myfunc: AnsiString;
asm
  push eax // save @result
  call system.@LStrClr
  mov    eax,3                 {Length}
{$ifdef UNICODE}
  mov    edx,1252 // code page for Delphi 2009/2010
{$endif}
  call   system.@NewAnsiString
  pop edx
  mov [edx],eax
  mov [eax],$303132
end;

سيعود سلسلة "210" ...

ومن الجيد دائمًا وضع كتلة {$ifdef UNICODE} لجعل الكود الخاص بك متوافقًا مع إصدار دلفي قبل عام 2009.

نصائح أخرى

بمساعدة ممتازة من A.Bouchez، تمكنت من تصحيح الكود الخاص بي، باستخدام LStrSetLength:

function myfunc: AnsiString;
asm

  push eax

  // eax = @result
  mov edx, 3
  mov ecx, 1252
  call System.@LStrSetLength

  pop eax

  mov ecx, [eax]

  mov [ecx], 'A'
  mov [ecx] + 1, 'B'
  mov [ecx] + 2, 'C'

end;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top