इनलाइन असेंबलर [जीसीसी, इंटेल, सी] का उपयोग करके, यह जांचने के लिए कि कैर्री फ्लैग ऑपरेशन के बाद सेट किया गया है या नहीं?जांचें कि क्या लेयर फ्लैग सेट है
उत्तर
सशर्त कूद के साथ jc
(ले जाने पर कूदें) या jnc
(कूदने पर कूदें)।
या आप झंडा कैरी स्टोर कर सकते हैं,
;; Intel syntax
mov eax, 0
adc eax, 0 ; add with carry
आह ठीक है, जेसी, जेएनसी, एडीसी कमांड नहीं पता था। Thx – hans
वार्निन, जीसीसी एटी एंड टी वाक्यविन्यास का उपयोग करता है। यह इंटेल वाक्यविन्यास है ... –
@Fififox, धन्यवाद। मैंने अपना जवाब संपादित किया। –
sbb %eax,%eax
स्टोर करेगा -1 eax में यदि कैरी ध्वज सेट है, 0 यदि यह स्पष्ट है। 0 को ईएक्स को पूर्व-साफ़ करने की आवश्यकता नहीं है; अपने आप से ईएक्स घटाना आपके लिए करता है। यह तकनीक बहुत शक्तिशाली हो सकती है क्योंकि आप सशर्त कूदों के उपयोग के बजाय गणना के परिणामों को संशोधित करने के लिए बिटमैस्क के रूप में परिणाम का उपयोग कर सकते हैं।
आपको अवगत होना चाहिए कि यह केवल वाहक ध्वज का परीक्षण करने के लिए मान्य है अगर यह इनलाइन एएसएम ब्लॉक के अंदर अंकगणित प्रदर्शन द्वारा निर्धारित किया गया था। आप सी कोड में किए गए एक गणना के परीक्षण का परीक्षण नहीं कर सकते हैं क्योंकि कंपाइलर कैरी फ्लैग को पकड़ने वाली चीजों को अनुकूलित/पुन: व्यवस्थित कर सकता है।
हालांकि x86 असेंबलर hes तेज़ एसईटीसीसी नामक एएलयू ध्वज परीक्षण निर्देश जहां सीसी वांछित एएलयू ध्वज है। तो अगर आप लिख सकते हैं:
साथsetc AL //will set AL register to 1 or clear to 0 depend on carry flag
or
setc byte ptr [edx] //will set memory byte on location edx depend on carry flag
or even
setc byte ptr [CarryFlagTestByte] //will set memory variable on location CarryFlagTestByte depend on carry flag
SETcc अनुदेश आप कैरी, शून्य, हस्ताक्षर, अतिप्रवाह या समता की तरह झंडे परीक्षण कर सकते हैं, कुछ SETcc निर्देश एक बार में दो झंडे परीक्षण करने के लिए अनुमति देते हैं।
संपादित करें: जोड़ा साधारण परीक्षण डेल्फी में की गई अवधि के बारे में संदेह गायब हो जाने की तेजी
procedure TfrmTest.ButtonTestClick(Sender: TObject);
function GetCPUTimeStamp: int64;
asm
rdtsc
end;
var
ii, i: int64;
begin
i := GetCPUTimeStamp;
asm
mov ecx, 1000000
@repeat:
mov al, 0
adc al, 0
mov al, 0
adc al, 0
mov al, 0
adc al, 0
mov al, 0
adc al, 0
loop @repeat
end;
i := GetCPUTimeStamp - i;
ii := GetCPUTimeStamp;
asm
mov ecx, 1000000
@repeat:
setc al
setc al
setc al
setc al
loop @repeat
end;
ii := GetCPUTimeStamp - ii;
caption := IntToStr(i) + ' ' + IntToStr(ii));
end;
पाश (1M पुनरावृत्तियों) अनुदेश का उपयोग कर जो SETC से अधिक से अधिक 5 गुना तेजी से है एडीसी प्रेरणा के साथ लूप।
संपादित करें: पंजीकरण में संग्रहीत परीक्षा परिणाम में दूसरा परीक्षण जोड़ा गया है, रजिस्टर में एएल कॉम्युलेटिव सीएल अधिक यथार्थवादी मामला है। SETcc अनुदेश के साथ
procedure TfrmTestOtlContainers.Button1Click(Sender: TObject);
function GetCPUTimeStamp: int64;
asm
rdtsc
end;
var
ii, i: int64;
begin
i := GetCPUTimeStamp;
asm
xor ecx, ecx
mov edx, $AAAAAAAA
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
shl edx, 1
mov al, 0
adc al, 0
add cl, al
end;
i := GetCPUTimeStamp - i;
ii := GetCPUTimeStamp;
asm
xor ecx, ecx
mov edx, $AAAAAAAA
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
shl edx, 1
setc al
add cl, al
end;
ii := GetCPUTimeStamp - ii;
caption := IntToStr(i) + ' ' + IntToStr(ii);
end;
Rutine हिस्सा अभी भी तेजी से लगभग 20% के लिए है।
क्या आपके पास उन्हें तेजी से कॉल करने के लिए उद्धरण है? मैंने पिछले कुछ पीढ़ियों के लिए नवीनतम सीपीयू के साथ नहीं रखा है, लेकिन लंबे समय तक, इन्हें धीमी विरासत ऑपकोड माना जाता था। –
@ आर .. इसमें कोई संदेह नहीं है: आप गलत हैं! ऊपरी परीक्षण की जांच करें! –
@ आर .. हाँ एसईटीसीसी पुराना निर्देश है, लेकिन एडीसी से बहुत तेज़ है या जेसी या जेएनसी जैसे सिंडिशन कूदता है। –
पहला फ़ंक्शन हस्ताक्षरित अतिरिक्त प्रदर्शन करता है और फिर लेयर फ्लैग (सीएफ) का उपयोग करके अतिप्रवाह के लिए परीक्षण करता है। अस्थिर रहना चाहिए। अन्यथा अनुकूलक निर्देशों को पुनर्व्यवस्थित करेगा, जो कि गलत परिणाम सुनिश्चित करता है। मैंने देखा है कि ऑप्टिमाइज़र jnc
को jae
(जो सीएफ पर भी आधारित है) में बदल गया है।
/* Performs r = a + b, returns 1 if the result is safe (no overflow), 0 otherwise */
int add_u32(uint32_t a, uint32_t b, uint32_t* r)
{
volatile int no_carry = 1;
volatile uint32_t result = a + b;
asm volatile
(
"jnc 1f ;"
"movl $0, %[xc] ;"
"1: ;"
: [xc] "=m" (no_carry)
);
if(r)
*r = result;
return no_carry;
}
अगला कार्य हस्ताक्षरित इंकों के लिए है। अस्थिरता का वही उपयोग लागू होता है। ध्यान दें कि हस्ताक्षर किए गए पूर्णांक गणित jno
के माध्यम से ध्वज पर कूदता है। मैंने देखा है कि ऑप्टिमाइज़र इसे jnb
(जो कि ओएस पर भी आधारित है) में बदल देता है।
/* Performs r = a + b, returns 1 if the result is safe (no overflow), 0 otherwise */
int add_i32(int32_t a, int32_t b, int32_t* r)
{
volatile int no_overflow = 1;
volatile int32_t result = a + b;
asm volatile
(
"jno 1f ;"
"movl $0, %[xo] ;"
"1: ;"
: [xo] "=m" (no_overflow)
);
if(r)
*r = result;
return no_overflow;
}
बड़ी तस्वीर में, आप निम्नानुसार कार्यों का उपयोग कर सकते हैं।एक ही बड़ी तस्वीर में, कई लोगों को शायद अतिरिक्त काम और सौंदर्य गैर सौंदर्य तक एक अतिप्रवाह/रैप से pwn'd/अधःप्रवाह
int r, a, b;
...
if(!add_i32(a, b, &r))
abort(); // Integer overflow!!!
...
इनलाइन जीसीसी विधानसभा जीसीसी में उपलब्ध है 3.1 और इसके बाद के संस्करण को अस्वीकार कर देंगे। Assembler Instructions with C Expression Operands देखें, या 'जीसीसी विस्तारित असेंबली' के लिए खोजें।
अंत में, दृश्य स्टूडियो में एक ही रूप में (कोड पीढ़ी में बहुत ज्यादा नहीं अंतर) इस प्रकार होगा, लेकिन वाक्य रचना बहुत आसान के बाद से MASM आप एक सी लेबल के लिए कूद करने की अनुमति देता है:
/* Performs r = a + b, returns 1 if the result is safe (no overflow), 0 otherwise */
int add_i32(__int32 a, __int32 b, __int32* r)
{
volatile int no_overflow = 1;
volatile __int32 result = a + b;
__asm
{
jno NO_OVERFLOW;
mov no_overflow, 0;
NO_OVERFLOW:
}
if(r)
*r = result;
return no_overflow;
}
बुरा पर पक्ष, उपरोक्त एमएएसएम कोड केवल x86 असेंबली के लिए लागू है। X64 असेंबली के लिए, कोई इनलाइनिंग नहीं है, इसलिए आपको इसे असेंबली (एक अलग फ़ाइल में) में कोड करना होगा और संकलन के लिए MASM64 का उपयोग करना होगा।
उदाहरण के लिए आप सी लेबल पर कूदने के लिए गोटो एक्सटेंशन का उपयोग कर सकते हैं एएसएम अस्थिर गोटो ("ja% एल [clabel]":: "स्मृति": clabel) ;, clabel सी लेबल –
पढ़ना @R द्वारा जवाब bellow है जहां .. आपके समारोह रद्द करने के लिए लगता है। 'आपको अवगत होना चाहिए कि यह केवल लेयर फ्लैग का परीक्षण करने के लिए मान्य है अगर यह इनलाइन एएसएम ब्लॉक के अंदर अंकगणित प्रदर्शन द्वारा निर्धारित किया गया था।' क्या आप इसके बारे में निश्चित हैं? –
@ डीआरबीको - हाँ, जीसीसी के लिए, यह निर्भर करता है। जीसीसी आपके ब्लॉक में निर्देशों की "निरंतरता" सुनिश्चित करेगा, लेकिन यह अपने निर्देशों को सम्मिलित/अंतःस्थापित कर सकता है। यदि जीसीसी निर्देश सीसी को संशोधित नहीं करते हैं, तो सब ठीक हो जाएगा। माइक्रोसॉफ्ट के इनलाइन असेंबलर जीसीसी की सीमाओं का सामना नहीं करते हैं। – jww
- 1. जांचें कि क्या नोड सेट में XSLT
- 2. कैसे जांचें कि कोई std :: स्ट्रिंग सेट है या नहीं?
- 3. जांचें कि क्या पर्यावरण चर पहले से सेट है
- 4. जांचें कि क्या जेएसपी खंड सेट किया गया है
- 5. जांचें कि क्या सी #
- 6. जांचें कि क्या संपत्ति फ़िंग
- 7. जांचें कि क्या स्ट्रिंग
- 8. जांचें कि क्या पाइथन
- 9. जांचें कि क्या एनएचबीरनेट
- 10. जांचें कि क्या MySQL
- 11. जांचें कि क्या हैशबल
- 12. जांचें कि क्या Guava
- 13. जांचें कि क्या लिनक्स
- 14. जांचें कि क्या एन्कोडिंग
- 15. जांचें कि क्या रूबी
- 16. जांचें कि सेट में मान पाइथन
- 17. जांचें कि क्या विजेट लेआउट में है Qt
- 18. जांचें कि क्या NSNumber अंश है
- 19. जांचें कि क्या NSURL स्थानीय फ़ाइल है
- 20. जांचें कि क्या NSNumber खाली है
- 21. पोस्टग्रेस्क्ल: जांचें कि क्या स्कीमा मौजूद है?
- 22. जांचें कि क्या BigDecimal पूर्णांक मान है
- 23. जांचें कि क्या इरादा यूरी उपलब्ध है
- 24. जांचें कि क्या नाम "मानव" लगता है?
- 25. जांचें कि क्या jQuery विधि मौजूद है
- 26. जांचें कि क्या XML तत्व मौजूद है
- 27. जांचें कि क्या mmap'ed पता सही है
- 28. जांचें कि क्या रजिस्ट्री कुंजी मौजूद है
- 29. जांचें कि क्या पाइथन पैकेज स्थापित है
- 30. बिटवाइज जांचें कि क्या ध्वज मौजूद है
आप इसे एएसएम के ब्लॉक में जांचना चाहते हैं या आप सी कोड में कुछ ले जाने के लिए लेयर फ्लैग की स्थिति को पास करना चाहते हैं जिसमें आपका एएसएम रेखांकित है? –
एएसएम के एक ब्लॉक के भीतर परीक्षण प्रत्यय है। इसे पार करना मुश्किल नहीं होना चाहिए। – hans