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来区分两个字符串的大小写位。 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
使用单字节指令递增的最佳方法。我想我们能xor al, [rdi]
/ stosb
。那将是相同的大小,但在这种loop
情况下可能更快(内存src +存储比内存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为例查看问题。这是Java 10 JDK还是Java 10 TIO编译器中的错误(或功能:S)?