问题具体是关于 UTF-8 在堆栈上占用多少空间,以及在内存(RAM)中占用多少空间,例如,它与 UTF-32 相同吗?因此,这与 UTF-8 序列化为文件时占用多少磁盘空间无关。抱歉,如果这种消除歧义的尝试侮辱了您的智力。
那么,当他们说 UTF-32 比 UTF-8 占用更多内存时,他们是什么意思?
编辑
UTF-32 使用更多内存,但是现在的计算机配备了很多 的记忆。节省内存的压力消失了,简单快捷 处理 UTF-32 字符串的重要性超过了增加的内存使用量。使用 UTF-32 使程序比任何试图保存的方法更快 通过检查字符串来记忆。
在您
push
多个单独的UTF-8编码单元(字节)的奇怪情况下,是的,这将使用UTF-8数据的每个字节8字节的堆栈空间。但仅限于这种情况。
这是非常低效的,这就是为什么人们不以这种方式编写代码(除了一些使用堆栈反转短字符串的简单初学者示例,作为理解入栈/出栈的后进先出顺序的学习练习)。
如果您想在堆栈空间中存储字符串数据,您需要保留一些空间(如本地
char
数组)并使用它,而不是将字节或双字解包为 qword。像 sub rsp, 64+8
/ movdqu xmm0, [rsi]
/ movdqa [rsp], xmm0
一样复制 16 个字节(UTF-32 或 UTF-8 数据,无论是哪一个)。
如果您确实想使用推送,您可以
push qword [rdi+rcx]
在推送时一次复制 8 个字节,从源字符串的末尾向后计数,以便字符串以与源相同的顺序结束在堆栈上。
访问数据时,可以使用
mov eax, [rsp + rcx*4]
表示 UTF-32(或者最好是指针增量,但比例因子有助于说明寻址)。或者对于 UTF-8,movzx eax, [rsp + rcx]
(如果您想将 unicode 代码点获取到 EAX 中,则使用循环检查多字节字符并可能加载更多字节)。将 UTF-8 的每个字节解压为 8 个字节毫无意义,并且使得高效处理多字节字符变得“更难”。例如使用 8 字节负载和 BMI2 pext
进行打包,也许 andn
/ tzcnt
/ bzhi
找到多字节字符的结尾(高位清零的字节)并将垃圾清零上面。