首先,我建议简单地使用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 解决方案,用于逐字节处理,不会像一次性转换多个字节那样提供如此大的加速,因为只会使用 XMM 寄存器的 1/8;您的函数不能(有效地)转换为按原样使用 SSSE3。如果您在循环中调用它(打印内存区域的 hexdump),那么使用像 Wojciech 的示例代码这样的函数将提供非常显着的加速。