mã máy x86-64, 14 byte
Có thể gọi từ C (quy ước gọi SysV x86-64) với nguyên mẫu này:
void casexchg(char *rdi, char *rsi); // modify both strings in place
Một phiên bản có độ dài rõ ràng với chiều dài trong rcx
cùng kích thước. void casexchg(char *rdi, char *rsi, int dummy, size_t len);
Điều này sử dụng cùng một thuật toán trao đổi bit như các câu trả lời C và Java: Nếu cả hai chữ cái là cùng một trường hợp, thì không cần phải thay đổi. Nếu họ ngược lại, cả hai cần phải thay đổi.
Sử dụng XOR để phân biệt bit trường hợp của hai chuỗi. mask = (a XOR b) AND 0x20
là 0 cho cùng hoặc 0x20 cho khác nhau. a ^= mask; b ^= mask
caseflip cả hai chữ cái nếu chúng là trường hợp ngược lại. (Vì mã chữ cái ASCII cho phần trên và phần dưới chỉ khác nhau ở bit 5.)
Danh sách NASM (từ nasm -felf64 -l/dev/stdout
). Sử dụng cut -b 26- <casexchg.lst >casexchg.lst
để biến điều này trở lại thành một cái gì đó bạn có thể lắp ráp.
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
Lệnh chậm loop
cũng là 2 byte, tương tự như một đoạn ngắn jcc
. scasb
vẫn là cách tốt nhất để tăng rdi
với lệnh một byte. Tôi đoán chúng ta có thể xor al, [rdi]
/ stosb
. Đó sẽ là cùng kích thước nhưng có thể nhanh hơn choloop
trường hợp (bộ nhớ src + store rẻ hơn bộ nhớ dst + tải lại). Và vẫn sẽ đặt ZF một cách thích hợp cho trường hợp độ dài ẩn!
Hãy thử trực tuyến! với một _start gọi nó trên argv [1], argv [2] và sử dụng sys_write trên kết quả
array[i++%n]+=...;
không?array[t=i++%n]=array[t]+...;
hoạt động tốt; và cũngarray[i%n]+=...;i++;
hoạt động tốt, nhưng sử dụngi++
hoặc++i
với một modulo và+=
nối vào một hàng trong một mảng không hoạt động .. Ở đây, ví dụ TIO Java 10 để xem vấn đề. Đây có phải là một lỗi (hoặc tính năng: S) trong Java 10 JDK hoặc trong trình biên dịch Java 10 TIO không?