машинний код x86-64, 14 байт
Телефонується з C (x86-64 SysV convention Convention) з цим прототипом:
void casexchg(char *rdi, char *rsi); // modify both strings in place
Версія з чіткою довжиною довжиною в rcx
- однаковий розмір. void casexchg(char *rdi, char *rsi, int dummy, size_t len);
Для цього використовується той самий біт-обмінник algo, як і відповіді C та Java: Якщо обидві літери є одним і тим же регістром, жодна з них не повинна змінюватися. Якщо вони протилежні, їх обом потрібно змінити.
Використовуйте XOR, щоб розрізняти біт регістру двох рядків. mask = (a XOR b) AND 0x20
дорівнює 0 для того ж або 0x20 для відмінності. a ^= mask; b ^= mask
caseflip обидва букви, якщо вони були протилежними. (Оскільки літери коду 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 пам'яті src + store дешевше, ніж dst пам'яті + перезавантаження). І все-таки встановив би 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?