x86-64 मशीन कोड, 14 बाइट्स
इस प्रोटोटाइप के साथ C (x86-64 SysV कॉलिंग कन्वेंशन) से कॉल करने योग्य:
void casexchg(char *rdi, char *rsi); // modify both strings in place
लंबाई के साथ एक स्पष्ट-लंबाई संस्करण rcx
समान आकार है। void casexchg(char *rdi, char *rsi, int dummy, size_t len);
यह सी और जावा के उत्तर के समान बिट-एक्सचेंज एल्गो का उपयोग करता है: यदि दोनों अक्षर एक ही मामले हैं, तो न तो बदलने की आवश्यकता है। यदि वे विपरीत मामले में हैं, तो उन्हें बदलने की आवश्यकता है।
दो तारों के मामले को अलग करने के लिए XOR का उपयोग करें। mask = (a XOR b) AND 0x20
भिन्न के लिए 0 या समान 0x20 है। a ^= mask; b ^= mask
केसफ्लिप दोनों पत्र यदि वे विपरीत मामले थे। (क्योंकि ऊपरी और निचले के लिए ASCII पत्र कोड केवल बिट 5 में भिन्न होते हैं)
एनएएसएम लिस्टिंग (से nasm -felf64 -l/dev/stdout
)। cut -b 26- <casexchg.lst >casexchg.lst
आप इसे इकट्ठा कर सकते हैं इसे वापस करने के लिए उपयोग करें ।
addr machine
6 code global casexchg
7 bytes casexchg:
8 .loop:
9 00000000 AC lodsb ; al=[rsi] ; rsi++
10 00000001 3207 xor al, [rdi]
11 00000003 2420 and al, 0x20 ; 0 if their cases were the same: no flipping needed
12
13 00000005 3007 xor [rdi], al ; caseflip both iff their cases were opposite
14 00000007 3046FF xor [rsi-1], al
15
16 0000000A AE scasb ; cmp al,[rdi] / inc rdi
17 ; AL=0 or 0x20.
18 ; At the terminating 0 in both strings, AL will be 0 so JNE will fall through.
19 ; 0x20 is ASCII space, which isn't allowed, so AL=0x20 won't cause early exit
20 0000000B 75F3 jne .loop
21 ; loop .loop ; caller passes explict length in RCX
22
23 0000000D C3 ret
size = 0xe bytes = 14
24 0000000E 0E db $ - casexchg_bitdiff
धीमी गति से loop
निर्देश भी 2 बाइट्स हैं, एक छोटे के रूप में jcc
। scasb
अभी भी rdi
एक-बाइट अनुदेश के साथ वेतन वृद्धि का सबसे अच्छा तरीका है । मुझे लगता है कि हम कर सकते थेxor al, [rdi]
/ stosb
। यह एक ही आकार होगा, लेकिन संभवतः के लिए तेज़ होगाloop
मामले के (मेमोरी src + स्टोर मेमोरी dst + reload की तुलना में सस्ता है)। और फिर भी निहित लंबाई के मामले के लिए उचित रूप से ZF सेट करेगा!
इसे ऑनलाइन आज़माएं! _start के साथ जो इसे argv [1] पर कॉल करता है, argv [2] और परिणाम पर sys_write का उपयोग करता है
array[i++%n]+=...;
?array[t=i++%n]=array[t]+...;
ठीक काम करता है; औरarray[i%n]+=...;i++;
ठीक काम करता है, लेकिन एक modulo का उपयोग करकेi++
या किसी सरणी में एक पंक्ति में संलग्न करने के लिए काम नहीं करता है .. यहाँ एक जावा 10 TIO उदाहरण के रूप में समस्या को देखने के लिए। क्या यह जावा 10 JDK में या जावा 10 TIO कंपाइलर में बग (या फीचर: S) है?++i
+=