我希望以尽可能短的汇编代码量反转字符串。
由于缺乏Unicorn支持,我只能使用SSSE3扩展或更少。我尝试访问ymm
即使SSSE3指令更简洁,用于128位XMM寄存器字节反转的16字节pshufb控制向量仍然占用16字节,使其更长。我对任何想法都持开放态度,但以下是我最好的尝试。
我需要32个字节或更少,越小越好。到目前为止,我得到的最好值是42,但我假设rdx(如果使用x86,则为ecx)内的字符串大小为30。
字符串地址位于rdx(如果使用x86,则为ecx)内部。
附加限制:不使用堆栈空间。此代码块必须在没有RSP指向可用堆栈内存的情况下运行。
标准x86 / 64 - 42字节
; get values in registers
mov rax, [rdx]
mov rbx, [rdx + 8]
mov rcx, [rdx + 16]
mov r8, [rdx + 24]
; swap bytes around
bswap rax
bswap rbx
bswap rcx
bswap r8
; shift it right by 2 because of the nulls
sar r8, 16
; put it back
mov [rdx], r8
mov [rdx + 0x6], rcx
mov [rdx + 0xE], rbx
mov [rdx + 0x16], rax
SSE3-62字节(因为字节数组,否则是46)
movdqu xmm3, [rip + 0x27]
movdqu xmm0, [rdx]
movdqu xmm1, [rdx] + 0x10
pshufb xmm0,xmm3
pshufb xmm1,xmm3
movdqu [rdx], xmm1
movdqu xmm1, [rdx+0x2]
movdqu [rdx], xmm1
movdqu [rdx+0xE], xmm0
hlt
; this would be tacked on to the end of the assembly as the rip + 0x27 value
\x00\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01
反转字符串最简洁的方法是将“字符串”定义为1字节的“方向和长度”字节,后跟最多127字节的字符。这允许您使用单个负字节指令(只需2个字节!)反转字符串。
示例(对于NASM):
myString:
db myString.end - myString.start
.start:
db "Hello World!"
.end:
;Reverse a string
;
;Input
; rdx Address of string to reverse
reverseString:
neg byte [rdx]
ret
当然,您必须编写其他例程来处理此字符串格式。例如:
;Print a string
;
;Input
; rsi Address of string to print
printString:
movsz rcx,byte [rsi] ;rcx = "direction and length" value
inc rsi
cmp rcx,0
jg .l1
je .done
std
neg rcx
.l1:
lodsb
call printChar ;Print the character in AL
loop .l1
cld
.done:
ret
;Get length of a string (in bytes)
;
;Input
; rsi Address of string
;
;Output
; rcx Length of string
getStringLength:
movsz rcx,byte [rsi] ;rcx = "direction and length" value
cmp rcx,0
jge .l1
neg rcx
.l1:
ret
以下31个字节的x86-64汇编器代码用于val strrev(char*p)
将就地反转任何长度的字符串(包括空字符串),只使用基本指令集。
然而,例程需要指向寄存器rdi中字符串的指针(与系统V ABI一致),而不是rdx。mov rdi、rdx将花费3个字节。此外,由于使用了两个隐式锁定的xchg,性能将非常糟糕。
小尺寸部分是由于创造性地使用单字节stosb指令的副作用,即根据方向标志分别读取和递增/递减rdi和rsi,可以通过单字节指令设置和清除方向标志。
如果代码是x86-32或者可以将自己限制为字符串
0000000000000000 <strrev>:
0: 31 c0 xor eax,eax
2: 48 8d 48 ff lea rcx,[rax-0x1]
6: 48 89 fe mov rsi,rdi
9: f2 ae repnz scas al,BYTE PTR es:[rdi]
b: 48 83 ef 02 sub rdi,0x2
f: 48 39 f7 cmp rdi,rsi
12: 7e 0a jle 1e <strrev+0x1e>
14: 86 07 xchg BYTE PTR [rdi],al
16: 86 06 xchg BYTE PTR [rsi],al
18: fd std
19: aa stos BYTE PTR es:[rdi],al
1a: fc cld
1b: ac lods al,BYTE PTR ds:[rsi]
1c: eb f1 jmp f <strrev+0xf>
1e: c3 ret
在x86汇编语言中,是否有任何有效的方法将字节转换为二进制数字字符串(表示为0和1的字节数组)?据我所知,x86汇编中没有任何“toString”函数,就像大多数高级编程语言一样。
本文向大家介绍Intel x86 Assembly& Microarchitecture x86汇编语言,包括了Intel x86 Assembly& Microarchitecture x86汇编语言的使用技巧和注意事项,需要的朋友参考一下 示例 x86汇编语言家族代表了最初的Intel 8086架构数十年来的进步。除了基于所使用的汇编器的几种方言外,多年来添加了附加的处理器指令,寄存器和其他功
本文向大家介绍JavaScript中最简洁的编码html字符串的方法,包括了JavaScript中最简洁的编码html字符串的方法的使用技巧和注意事项,需要的朋友参考一下 html字符串是指'<div id=”a”>aklsdjfklsjdfl</div>'这样的带html特殊符号的字符串,我们通常要对他进行处理再输出以免输出成了真正的html元素,也就是把<变成<这样的html符号代码。
反转这个ArrayList的最简单方法是什么?
问题内容: 将格式化的字符串转换为日历的最简单,最简单的方法是什么?例如将“ dd.MM.yyyy”添加到日历? 问题答案: DateFormat df = new SimpleDateFormat(“dd.MM.yyyy”); Calendar cal = Calendar.getInstance(); cal.setTime(df.parse(stringInstanceRepresentin
假设我们有两个寄存器长度2有符号1整数,例如