2015-07-23 9 views
5

मैं एक एक्स 64 एएसएम ब्लॉक में अपवाद उठाना चाहता हूं।मैं एएसएम ब्लॉक में अपवाद कैसे बढ़ा सकता हूं?

चलें मान मैं बहुत की तरह एक समारोह है:

function Example(Values: array of integer): integer; 
asm 
    or rcx,rcx 
    jz @error 
    .... 

मैं जानता हूँ कि मैं सिर्फ सूचक पढ़ सकते हैं और एक ए वी प्राप्त कर सकते हैं, हालांकि मैं एक और वर्णनात्मक त्रुटि को बढ़ाने के लिए चाहते हैं।

मैं एक अतिरिक्त समारोह बनाने के लिए और कॉल एक है कि हो सकता है:

asm 
    or rcx,rcx 
    jz @error 
    .... 
@error: 
    mov ecx, 1 
    mov rdx, ErrorString 
    jmp RaiseError 
    .... 

function RaiseError(code: integer; const Msg: string); 
begin 
    case code of 
    1: raise EEmptyArrayError.Create(Msg); 

हालांकि त्रुटि तो समारोह है, जिसमें कारण होता था बाहर हो जाएगा। मैं Example फ़ंक्शन के अंदर से उत्पन्न होने के लिए अपवाद कैसे प्राप्त करूं (प्रतीत होता हूं)।

ध्यान दें कि यह X64 है, इसलिए X86 पर लागू होने वाले सभी एसईएच उत्तर अच्छे नहीं हैं क्योंकि X64 VEH का उपयोग करता है।

+2

मुझे लगता है कि यह अभी भी x64 में एसईएच है। और बस कुछ पास्कल लिखें और देखें कि संकलक इसे कैसे काम करता है। –

+1

चूंकि कोई और पूछने वाला नहीं है, अगर कोड इतना उच्च स्तर है कि आप इसे अपवाद उठाना चाहते हैं, तो आप इसे पहले स्थान पर क्यों लिख रहे हैं? – alcalde

+0

क्योंकि इसे एसएसई निर्देशों की आवश्यकता है, और मेरे पास एसएसई-इंट्रिनिक्स नहीं है। – Johan

उत्तर

4

उठाने का पूरा वाक्य रचना है:

raise Exception at address 

तुम सब करने की ज़रूरत है वर्तमान आईपी एक पैरामीटर और त्रुटि proc कि पारित कर सकते हैं अपवाद के लिए पर के रूप में पारित करने के लिए है।

आप lea rax, [rip] का उपयोग कर आरआईपी प्राप्त कर सकते हैं।

इस प्रकार कोड हो जाता है:

asm 
    or rcx,rcx 
    jz @error 
    .... 
@error: 
    mov ecx, 1 
    mov rdx, ErrorString 
    lea r8,[rip] 
    jmp RaiseError 
    .... 

function RaiseError(code: integer; const Msg: string; address: pointer); 
begin 
    case code of 
    1: raise EEmptyArrayError.Create(Msg) at address; 
इस मामले में यह आसान है में बेशक

उपयोग करने के लिए

function RaiseError(code: integer; const Msg: string); 
begin 
    case code of 
    1: raise EEmptyArrayError.Create(Msg) at ReturnAddress; 

नोट
इस मामले में अगर आप JMP त्रुटि ऐसा लगेगा रखना कॉलिंग रूटीन से निकलती है, इस मामले में यह वास्तव में सही है। यदि आप अपने एएसएम कोड पर दोषी उंगली को इंगित करने के अपवाद चाहते हैं तो कॉल का उपयोग करें।

+3

डेल्फी XE2 + में, आप 'System.ReturnAddress' कंपाइलर आंतरिक का उपयोग कर सकते हैं (और चाहिए), जो 32 बिट और 64 बिट दोनों में काम करता है:' प्रक्रिया RaiseError (कोड: पूर्णांक; const संदेश: स्ट्रिंग); शुरू करें ... EEmptyArrayError को बढ़ाएं। ReturnAddress पर बनाएं (संदेश); ... अंत; ' –

+0

मुझे लगता है कि 'रिटर्नएड्रेस' के साथ 'RaiseError' संस्करण' का उपयोग करते समय आपको 'jmp RaiseError'' के बजाय 'कॉल RaiseError'' का उपयोग करना होगा। – JRL

+0

@ जेआरएल नहीं जेएमपी सही है। इस मामले में त्रुटि मेरे एएसएम कोड में नहीं है, त्रुटि उस दिनचर्या में है जो उस कोड को शून्य पैरामीटर के साथ कॉल करती है। अपवाद को प्रदर्शित करना चाहिए। अन्यथा उपयोगकर्ता गलत दिनचर्या डीबग करेगा। – Johan

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