2012-05-16 7 views
5

का उपयोग करके कक्षा उदाहरण बनाएं, मैं क्या करना चाहता हूं, असेंबली का उपयोग करके, क्लास इंस्टेंस बनाएं, इसके तरीकों में से एक को कॉल करें और फिर इंस्टेंस को मुक्त करें।डेल्फी इनलाइन असेंबलर

मुझे पता है कि मुझे कुछ बहुत महत्वपूर्ण और शायद बहुत आसान याद आ रही है, लेकिन मुझे नहीं पता कि क्या।

program Project2; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TSomeClass = class(TObject) 
    private 
    FCreateDateTime: string; 
    public 
    constructor Create; 
    procedure SayYeah; 
    end; 

constructor TSomeClass.Create; 
begin 
    FCreateDateTime := DateTimeToStr(Now); 
end; 

procedure TSomeClass.SayYeah; 
begin 
    Writeln('yeah @ ' + FCreateDateTime); 
end; 

procedure Doit; 
asm 
    CALL TSomeClass.Create; // <= Access Violation 
    CALL TSomeClass.SayYeah; 
    CALL TSomeClass.Free; 
end; 

begin 
    try 
    Doit; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 

FYI करें: मैं समझता हूँ कि कैसे मैं इसे करने का एक और तरीका है निम्न स्तर पर इस लक्ष्य को हासिल कर सकते हैं, चाहते हैं।

अद्यतन:, बल्कि PUSH से

EBX का उपयोग कर दोष खोजने के लिए अरनॉड के लिए धन्यवाद:

Update2:

एंड्रियास Rejbrand के लिए धन्यवाद, मैं अपराधी को खोजने के प्रबंधित किया है/पीओपी ईएक्स

var 
    TSomeClass_TypeInfo: Pointer; 

procedure Doit; 
asm 
    MOV DL, $01; 
    MOV EAX, TSomeClass_TypeInfo; 
    CALL TSomeClass.Create; 
    PUSH EAX; 
    CALL TSomeClass.SayYeah; // call method 
    POP EAX; 
    MOV DL, $01; 
    CALL TSomeClass.Free; // pointer to instance(Self) is expected in EAX 
end; 

begin 
    TSomeClass_TypeInfo := TSomeClass; 
    try 
    Doit; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 
+1

EBX बचाया जा करने की जरूरत है -, अरनॉड का जवाब – PhiS

+0

@PhiS हाँ महोदय, मैं अरनॉड का जवाब, जिसे इस में रुचि रखता है पढ़ा है पर एक नजर है सभी उत्तर (केवल 2) और टिप्पणियां (पढ़ा जाएगा: – ComputerSaysNo

+0

बात है कि प्रश्न के आपके अपडेट में आप इसे सहेजने के बिना ईबीएक्स का उपयोग कर रहे हैं। कृपया इसे ठीक करें (उदाहरण के लिए पुश ईबीएक्स/पॉप ईबीएक्स), क्योंकि यदि आप जोखिम नहीं चलाते हैं तो ऐसे फ़ंक्शन का उपयोग करने वाला वास्तविक प्रोग्राम बस क्रैश हो सकता है - और इसके लिए कारण खोजना बहुत मुश्किल होगा ... – PhiS

उत्तर

2

आप इसके बारे में एक में पढ़ सकते हैं डेल्फी असेंबली प्रोग्रामिंग के लिए उत्कृष्ट गाइड, मूल रूप से here मिला। दुर्भाग्यवश, साइट डाउन है, लेकिन आप एक संग्रहीत संस्करण here पा सकते हैं। विशेष रूप से page 5 पर देखें।

+0

+1 और स्वीकार किया गया, बहुत बहुत धन्यवाद !! – ComputerSaysNo

+0

जबकि यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, हम चाहते हैं कि आप शामिल करना चाहते हैं आपके उत्तर में लिंक किए गए आलेख के आवश्यक भाग, और [संदर्भ के लिए लिंक] प्रदान करें (http://meta.stackexchange.com/q/8259)। ऐसा करने में विफल होने से उत्तर छोड़ देता है लिंक सड़ांध से जोखिम नहीं है। – Kev

+3

@ केवी: मैं इसके बारे में पूरी तरह से अवगत हूं, और यही वजह है कि ऐसा करने के अनुरोध के बाद मैंने केवल यही जवाब भेजा। मूल रूप से, मैंने केवल लिंक को एक टिप्पणी के रूप में दिया, हालांकि यह अब स्पष्ट नहीं है (चूंकि आपने टिप्पणियां हटा दी हैं)। दुर्भाग्यवश, मेरे पास लिंक किए गए पृष्ठ पर विषयों को जानने के लिए अभी समय/ऊर्जा नहीं है। –

10

आपका एएसएम कोड सही नहीं है।

आप ebx रजिस्टर अधिभारित कर रहे हैं, जिसे संरक्षित किया जाना चाहिए। और वैश्विक परिवर्तनीय चाल समझ में नहीं आता है।

एक बेहतर कोडिंग होना चाहिए:

procedure Doit(ClassType: pointer); 
asm // eax=TList 
    mov dl,true // hidden boolean 2nd parameter 
    call TObject.Create 
    push eax 
    call TList.Pack 
    pop eax 
    call TObject.Free 
end; 

DoIt(TList); 

लेकिन यह एक try...finally साथ उदाहरण रक्षा नहीं करता। :)

बारे mov dl,true पैरामीटर, this official page from the EMB wiki देखें:

निर्माणकर्ता और विनाशकर्ता अन्य तरीकों के रूप में ही बुला परंपराओं का उपयोग, सिवाय इसके कि एक अतिरिक्त बूलियन ध्वज पैरामीटर में भेजा जाता है निर्माता के संदर्भ से संकेत मिलता है या विनाशक कॉल।

एक निर्माता कॉल का झंडा पैरामीटर में झूठी का मान दर्शाता है कि निर्माता एक उदाहरण वस्तु के माध्यम से लागू किया गया था या विरासत में मिला कीवर्ड का उपयोग। इस मामले में, कन्स्ट्रक्टर सामान्य विधि की तरह व्यवहार करता है। कन्स्ट्रक्टर कॉल के ध्वज पैरामीटर में सही का मान इंगित करता है कि निर्माता को कक्षा संदर्भ के माध्यम से बुलाया गया था। इस मामले में, कन्स्ट्रक्टर स्वयं द्वारा दी गई कक्षा का उदाहरण बनाता है, और ईएक्स में नव निर्मित ऑब्जेक्ट का संदर्भ देता है।

एक विनाशक कॉल के ध्वज पैरामीटर में झूठा का मूल्य इंगित करता है कि विरासत को विरासत वाले कीवर्ड का उपयोग करके बुलाया गया था। इस मामले में, विनाशक एक सामान्य विधि की तरह व्यवहार करता है। एक विनाशक कॉल के ध्वज पैरामीटर में True का मान इंगित करता है कि विनाशक को एक आवृत्ति ऑब्जेक्ट के माध्यम से बुलाया गया था।इस मामले में, विनाशक लौटने से पहले स्वयं द्वारा दिए गए उदाहरण को हटा देता है।

ध्वज पैरामीटर व्यवहार करता है जैसे कि यह अन्य सभी पैरामीटर से पहले घोषित किया गया था। रजिस्टर सम्मेलन के तहत, यह डीएल रजिस्टर में पारित किया जाता है। पास्कल सम्मेलन के तहत, इसे अन्य सभी पैरामीटर से पहले धक्का दिया जाता है। Cdecl, stdcall, और safecall सम्मेलनों के तहत, यह स्वयं पैरामीटर से ठीक पहले धक्का दिया गया है।

के बाद से डीएल रजिस्टर इंगित करता है कि निर्माता या नाशक कॉल स्टैक में सबसे बाहरी है, तो आप ऐसा बाहर निकलने BeforeDestruction या AfterConstruction ठीक से कहा जा सकता है कि इससे पहले कि डीएल का मूल्य पुनर्स्थापित करना होगा।

तो एक वैकल्पिक मान्य कोडिंग, eax के बाद से हमारे वस्तु नहीं है nil तो हम सीधे नाशक कॉल कर सकते हैं, हो सकता है:

procedure Doit(ClassType: pointer); 
asm // eax=TList 
    mov dl,true 
    call TObject.Create 
    push eax 
    call TList.Pack 
    pop eax 
    mov dl,true 
    call TList.Destroy 
end; 

सभी मामले में, वस्तु asm से पहुंच उपलब्ध कराना नहीं है इस तरह से किया जाना है। आपके पास सीधे प्रकार की जानकारी तक पहुंच नहीं है, इसलिए इसके साथ काम करना बहुत मुश्किल हो सकता है। मौजूदा class उदाहरण के साथ, आप जो भी चाहें asm विधियों के साथ कर सकते हैं; लेकिन उदाहरण बनाने के लिए, और वर्ग प्रकारों के साथ खेलें, asm निश्चित रूप से प्राकृतिक तरीका नहीं है!

+0

+1 कैच के लिए धन्यवाद, साइड नोट: मैं आपसे निजी रूप से संपर्क करना चाहता था (आपकी कुछ परियोजनाओं के बारे में), क्या आप मुझे एक लिंक दे सकते हैं जहां मैं अपना ई-मेल प्राप्त कर सकता हूं या इसे सीधे दे सकता हूं? – ComputerSaysNo

+0

@DorinDuminica यदि यह synopse प्रोजेक्ट्स के बारे में है, तो मुख्य प्रविष्टि बिंदु http://synopse.info पर फ़ोरम है लेकिन आप सीधे synopse dot info पर webcontact01 को भी लिख सकते हैं :) –

+0

धन्यवाद, आपको – ComputerSaysNo

संबंधित मुद्दे