kode mesin x86-64, 14 byte
Callable from C (konvensi pemanggilan SysV x86-64) dengan prototipe ini:
void casexchg(char *rdi, char *rsi); // modify both strings in place
Versi eksplisit-panjang dengan panjang dalam rcx
adalah ukuran yang sama. void casexchg(char *rdi, char *rsi, int dummy, size_t len);
Ini menggunakan bit-exchange algo yang sama dengan jawaban C dan Java: Jika kedua huruf sama, tidak perlu diubah. Jika mereka bertolak belakang, mereka berdua perlu berubah.
Gunakan XOR untuk membedakan bit case dari dua string. mask = (a XOR b) AND 0x20
adalah 0 untuk sama atau 0x20 untuk berbeda. a ^= mask; b ^= mask
caseflip kedua huruf jika mereka kasus sebaliknya. (Karena kode huruf ASCII untuk atas dan bawah hanya berbeda dalam bit 5.)
Daftar NASM (dari nasm -felf64 -l/dev/stdout
). Gunakan cut -b 26- <casexchg.lst >casexchg.lst
untuk mengubah ini kembali menjadi sesuatu yang dapat Anda kumpulkan.
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
Instruksi lambat juga 2 byte, sama dengan pendek jcc
. scasb
masih merupakan cara terbaik untuk meningkatkan rdi
instruksi satu byte. Saya kira kita bisa xor al, [rdi]
/ stosb
. Itu akan menjadi ukuran yang sama tetapi mungkin lebih cepat untuk loop
kasus ini (memory src + store lebih murah daripada memory dst + reload). Dan masih akan mengatur ZF dengan tepat untuk kasus panjang implisit!
Cobalah online! dengan _start yang memanggilnya pada argv [1], argv [2] dan menggunakan sys_write pada hasilnya
array[i++%n]+=...;
?array[t=i++%n]=array[t]+...;
bekerja dengan baik; danarray[i%n]+=...;i++;
berfungsi dengan baik juga, tetapi menggunakani++
atau++i
dengan modulo dan+=
untuk menambahkan ke baris dalam array tidak berfungsi .. Berikut Java 10 TIO sebagai contoh untuk melihat masalahnya. Apakah ini bug (atau fitur: S) di Java 10 JDK atau di compiler Java 10 TIO?