2010-03-07 16 views
5

मैं डेल्फी 7 में एक एएसएम समारोह लिखा लेकिन यह कुछ और करने के लिए अपने कोड बदल देती है:डेल्फी लेबल और एएसएम अजीबता?

function f(x: Cardinal): Cardinal; register; 
label err; 
asm 
    not eax 
    mov edx,eax 
    shr edx, 1 
    and eax, edx 
    bsf ecx, eax 
    jz err 
    mov eax, 1 
    shl eax, cl 
    mov edx, eax 
    add edx, edx 
    or eax, edx 
    ret 
    err: 
    xor eax, eax 
end; 

// compiled version 
f: 
    push ebx  // !!! 
    not eax 
    mov edx,eax 
    shr edx, 1 
    and eax, edx 
    bsf ecx, eax 
    jz +$0e 
    mov eax, 1 
    shl eax, cl 
    mov edx, eax 
    add edx, edx 
    or eax, edx 
    ret 
    err: 
    xor eax, eax 
    mov eax, ebx // !!! 
    pop ebx  // !!! 
    ret 

// the almost equivalent without asm 
function f(x: Cardinal): Cardinal; 
var 
    c: Cardinal; 
begin 
    x := not x; 
    x := x and x shr 1; 
    if x <> 0 then 
    begin 
    c := bsf(x); // bitscanforward 
    x := 1 shl c; 
    Result := x or (x shl 1) 
    end 
    else 
    Result := 0; 
end; 

यह push ebx और pop ebx क्यों उत्पन्न करता है? और यह mov eax, ebx क्यों करता है?

ऐसा लगता है कि यह mov eax, ebx की वजह से आंशिक स्टैक फ्रेम उत्पन्न करता है।

यह साधारण परीक्षण mov eax, edx उत्पन्न करता है लेकिन यह है कि स्टैक फ्रेम उत्पन्न नहीं करता है:

function asmtest(x: Cardinal): Cardinal; register; 
label err; 
asm 
    not eax 
    and eax, 1 
    jz err 
    ret 
    err: 
    xor eax, eax 
end; 

// compiled 
asmtest: 
    not eax 
    and eax, $01 
    jz +$01 
    ret 
    xor eax, eax 
    mov eax, edx // !!! 
    ret 

ऐसा लगता है यह label err के साथ कुछ किया है। अगर मैं इसे हटा देता हूं तो मुझे mov eax, * भाग नहीं मिलता है।

ऐसा क्यों होता है?


Quality Central पर एक बग रिपोर्ट बनाई गई।

+0

http://qc.embarcadero.com/wc/qcmain.aspx –

+0

@Jeroen यकीन है कि एक बग के रूप में इसकी रिपोर्ट करें। कोई जांच नहीं ... – Egon

+0

आपने यहां कई "क्यों" प्रश्न पूछे हैं, लेकिन आपके द्वारा स्वीकार किए गए प्रतिक्रिया से उनमें से कोई भी उत्तर नहीं दिया गया था। ऐसा लगता है कि आप वास्तव में जानना चाहते थे कि डेल्फी असेंबलर में एक नए निर्देश के लिए कैसे कूदना है, इस बात के बावजूद कि आपके अपने प्रयास विफल क्यों हुए। क्या यह सही है? –

उत्तर

7

व्यावहारिक सलाह है: एएसएम कोड में लेबल कीवर्ड का उपयोग नहीं करते, का उपयोग @@ - उपसर्ग के लेबल:

function f(x: Cardinal): Cardinal; register; 
asm 
    not eax 
    mov edx,eax 
    shr edx, 1 
    and eax, edx 
    bsf ecx, eax 
    jz @@err 
    mov eax, 1 
    shl eax, cl 
    mov edx, eax 
    add edx, edx 
    or eax, edx 
    ret 
@@err: 
    xor eax, eax 
end; 

अपडेट किया गया:

मैं नहीं बग रिपोर्ट मिल गया है Basm area में। यह एक बग की तरह दिखता है, लेकिन मैंने कई वर्षों तक बीएएसएम का उपयोग किया है और कभी भी लेबल कीवर्ड का उपयोग करने के बारे में सोचा नहीं है। असल में मैंने कभी डेल्फी में लेबल कीवर्ड का उपयोग नहीं किया। :)

+0

वाह, जो इसे ठीक करता है ... –

+0

कोई विचार क्यों 'लेबल' उत्पन्न करता है 'mov eax, * 'thingy ... क्या यह एक बग है? या बस कुछ अजीब व्यवहार? – Egon

+0

@@ MyLabel के बजाय, @MyLabel (एक "@" के साथ) asm..end ब्लॉक में ठीक है। – PhiS

1

खैर ... वापस तो, डेल्फी-नियम-पुस्तक में, यह संकलक-अनुकूलन के बारे में कुछ और thealike-crazyness कहा करते थे:


संकलक केवल नेस्टेड दिनचर्या के लिए Stackframes उत्पन्न करता है, के लिए ढेर-पैरामीटर के साथ दिनचर्या के लिए स्थानीय चर और होने दिनचर्या

स्वत: जनरेट Initialization- और Finalizationcode दिनचर्या के लिए शामिल हैं:

PUSH EBP    ; If Locals <> 0 or Params <> 0 
MOV  EBP,ESP   ; If Locals <> 0 or Params <> 0 
SUB  ESP,Locals  ; If Locals <> 0 
    ... 
MOV  ESP,EBP   ; If Locals <> 0 
POP  EBP    ; If Locals <> 0 or Params <> 0 
RET  Params   ; Always 

यदि स्थानीय वैरिएबल में वेरिएंट, लांग स्ट्रिंग्स या इंटरफेस होते हैं तो उन्हें नल के साथ प्रारंभ किया जाता है लेकिन बाद में अंतिम रूप नहीं दिया जाता है।

स्थानीय स्थानीय चर का आकार है, पैरामीटर्स का आकार पैराम्स। यदि दोनों स्थानीय और पैराम नल हैं तो नल नो इट-कोड उत्पन्न होगा और अंतिमकरण कोड में केवल आरईटी-इंस्ट्रक्शन शामिल होगा।


हो सकता है कि यह सब के साथ कुछ मिल गया है ...

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