x86-64マシンコード、14バイト
このプロトタイプでC(x86-64 SysV呼び出し規約)から呼び出し可能:
void casexchg(char *rdi, char *rsi); // modify both strings in place
長さがinの明示的な長さのバージョンrcx
は同じサイズです。 void casexchg(char *rdi, char *rsi, int dummy, size_t len);
これは、CおよびJavaの回答と同じビット交換アルゴリズムを使用します。 両方の文字が同じ場合、どちらも変更する必要はありません。逆の場合は、両方を変更する必要があります。
XORを使用して、2つの文字列の大文字小文字を区別します。 mask = (a XOR b) AND 0x20
同じ場合は0、異なる場合は0x20です。 a ^= mask; b ^= mask
大文字と小文字が逆の場合は、両方の文字を反転します。 (上位と下位の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バイトで、shortと同じjcc
です。 scasb
それでも、rdi
1バイトの命令でインクリメントする最良の方法です。できると思うxor al, [rdi]
stosb
ます/ 。それは同じサイズですが、おそらくloop
ケースの方が高速です(メモリsrc +ストアはメモリdst +リロードよりも安価です)。そして、暗黙の長さの場合にZFを適切に設定します!
オンラインでお試しください!argv [1]、argv [2]で呼び出し、結果にsys_writeを使用する_start
array[i++%n]+=...;
か?array[t=i++%n]=array[t]+...;
正常に動作します; とarray[i%n]+=...;i++;
同様に正常に動作しますが、モジュロを使用しi++
たり、配列内の行に追加したりしても機能しません。これは、Java 10 JDKまたはJava 10 TIOコンパイラのバグ(または機能:S)ですか?++i
+=