首先,我建议简单地使用itoa()
,例如:
static inline void hextoasacii(char *a_src, char *a_dest)
{
(void)itoa(*a_src, a_dest, 16);
}
但这有一个缺点,a_dest
会被NULL
它终止,即它需要三个(而不是两个)字节的空间,所以这不是 100% 等效的。
在任何情况下,显示的内联汇编代码对于内存访问都不是特别优化;C/C++ 中的原始形式(但它当然取决于 255 项大小的hexlu[]
数组的确切内容,我假设它看起来像)将是:char *hexlu[] = { "00", "01", "02", ... };
static inline void hextoascii(char *a_src, char *a_dest)
{
static const char hexdigits[16] = "0123456789abcdef";
int src = *a_src;
a_dest[0] = hexdigits[src >> 4];
a_dest[1] = hexdigits[src & 15];
// make this:
// *(unsigned short*)a_dest =
// ((unsigned short)hexdigits[src & 15]) << 8 |
// (unsigned short)hexdigits[src >> 4]
//
// if it absolutely _must_ be a single store
}
边注:
如果您真的想采用汇编方式进行二进制/十六进制转换,可以使用 SSSE3 ( pshufb
) 对上述内容进行编码以进行 16 字符表查找。这样,等效的sprintf("%llx", tgt_string, val_uint64)
基本上可以在一条指令 pshufb
中完成。
示例如何执行此操作并解释其工作原理,请参见此处:
一个 SSSE3 解决方案,用于逐字节进行,不会像一次性转换多个字节那样提供如此大的加速,因为只会使用 1/8 的XMM
寄存器;您的函数不能(有效地)转换为按原样使用 SSSE3。如果您在循环中调用它(打印内存区域的十六进制转储),那么使用像 Wojciech 的示例代码这样的函数将提供非常显着的加速。