รหัสเครื่อง 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);
สิ่งนี้ใช้อัลโกแลกเปลี่ยนบิตเดียวกันกับคำตอบ C และ Java: หากตัวอักษรทั้งสองเป็นตัวพิมพ์เล็กไม่จำเป็นต้องเปลี่ยน หากพวกเขาเป็นกรณีตรงข้ามพวกเขาทั้งสองต้องเปลี่ยน
ใช้ XOR เพื่อ diff บิตเคสของสองสตริง mask = (a XOR b) AND 0x20
เป็น 0 สำหรับเดียวกันหรือ 0x20 สำหรับการแตกต่างกัน a ^= mask; b ^= mask
caseflip ตัวอักษรทั้งสอง iff พวกเขาเป็นกรณีตรงข้าม (เนื่องจากรหัสตัวอักษร ASCII สำหรับบนและล่างแตกต่างกันในบิตที่ 5 เท่านั้น)
รายชื่อ NASM (จาก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 + store ราคาถูกกว่า memory dst + reload) และจะยังคงตั้งค่า ZF อย่างเหมาะสมสำหรับกรณีความยาวโดยนัย!
ลองออนไลน์! ด้วย _start ที่เรียกใช้บน argv [1], argv [2] และใช้ sys_write กับผลลัพธ์
array[i++%n]+=...;
หรือไม่array[t=i++%n]=array[t]+...;
ทำงานได้ดี; และarray[i%n]+=...;i++;
ทำงานได้ดีเช่นกัน แต่การใช้i++
หรือ++i
กับโมดูโล่และ+=
เพื่อผนวกเข้ากับแถวในอาร์เรย์ใช้งานไม่ได้ .. ที่นี่ Java 10 TIO เป็นตัวอย่างเพื่อดูปัญหา นี่เป็นข้อบกพร่อง (หรือคุณสมบัติ: S) ใน Java 10 JDK หรือในคอมไพเลอร์ Java 10 TIO หรือไม่