kod maszynowy x86-64, 14 bajtów
Wywoływany z C (konwencja wywoływania SysV x86-64) z tym prototypem:
void casexchg(char *rdi, char *rsi); // modify both strings in place
Wersja o jawnej długości z długością w rcx
ma ten sam rozmiar. void casexchg(char *rdi, char *rsi, int dummy, size_t len);
Używa tego samego algo wymiany bitów, co odpowiedzi C i Java: Jeśli obie litery są takie same, żadna nie musi się zmienić. Jeśli są w przeciwnym przypadku, oboje muszą się zmienić.
Użyj XOR, aby różnicować bit wielkości dwóch ciągów. mask = (a XOR b) AND 0x20
wynosi 0 dla tego samego lub 0x20 dla różnicy. a ^= mask; b ^= mask
caseflip obie litery, jeśli były przeciwne. (Ponieważ kody liter ASCII dla górnej i dolnej różnią się tylko bitem 5).
Lista NASM (od nasm -felf64 -l/dev/stdout
). Użyj, cut -b 26- <casexchg.lst >casexchg.lst
aby zmienić to z powrotem w coś, co możesz złożyć.
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
Wolna loop
instrukcja ma również 2 bajty, tak samo jak krótka jcc
. scasb
jest wciąż najlepszym sposobem na zwiększenie rdi
instrukcji jednobajtowej. Chyba moglibyśmy xor al, [rdi]
/ stosb
. Byłby to ten sam rozmiar, ale prawdopodobnie szybszy dlaloop
przypadku (pamięć src + sklep jest tańsza niż pamięć dst + przeładowanie). I nadal ustawiłby ZF odpowiednio dla przypadku o niejawnej długości!
Wypróbuj online! z _start, który wywołuje go na argv [1], argv [2] i używa sys_write na wyniku
array[i++%n]+=...;
?array[t=i++%n]=array[t]+...;
działa w porządku; iarray[i%n]+=...;i++;
działa również dobrze, ale używaniei++
lub++i
z modulo i+=
dołączanie do wiersza w tablicy nie działa. Tutaj TIO Java 10 jako przykład, aby zobaczyć problem. Czy to błąd (lub funkcja: S) w JDK Java 10 lub w kompilatorze Java 10 TIO?