我在 eax
中存储了一个 UTF-8 字符后来,在处理中,我需要知道有多少字节组成了字符。
我已经缩小了范围,最大限度地减少了变化和掩码,想知道我是否在某处错过了一些巧妙的技巧?
选项 1:蛮力
mov r11, 4 ; Maximum bytes
bt eax, 31 ; Test 4th MSB
jc .exit
dec r11 ; Lets try 3
bt eax, 23 ; Test 3rd MSB
jc .exit
dec r11 ; Lets try 2
bt eax, 15 ; Test 2nd MSB
jc .exit
dec r11 ; It's straight up ascii (1 byte)
.exit:
注:
eax
中积累了正如每个人所指出的那样注册错误。 最佳答案
如果您可以假设 correct encoding of the character ,您可以简单地检查第一个代码单元中最高零的位置(感谢 UTF-8 的自动同步属性)。
罪魁祸首是对于一个代码单元的代码点,最高零是第 7 位。对于 n 个代码单元的代码点,最高位是 7 - n(注意“不连续性”)。
假设第一个代码单元在 al
.
not al ;Trasform highest 0 in highest 1
bsr al, al ;Find the index (from bit0) of the first 1 from the left
xor al, 7 ;Perform 7 - index
;This gives 0 for single code unit code points
mov ah, 1
cmovz al, ah ;Change back to 1
请注意
bsr
没有为 0 的输入定义,但这只会发生在无效的前导代码单元(值为 11111111b)。您可以使用
jz <error handler>
检测无效的 0xff 代码单元后 bsr
操作说明。感谢@CodyGray 指出原始版本的错误。
感谢@PeterCorders 指出执行 7 - AL 的 XOR 技巧。
关于assembly - 32 位寄存器中非零字符的高效 UTF-8 字符长度解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41264555/