void HexToStr(const char *lpszInStr, int nInLen, char *lpszHex) {
  int i, j = 0;
  char l_byTmp;
  for (i = 0; i < nInLen; i++) {
    l_byTmp = (lpszInStr[i] & 0xf0) >> 4;
    if (l_byTmp < 10)
      lpszHex[j++] = l_byTmp + '0';
    else
      lpszHex[j++] = l_byTmp - 10 + 'A';
    l_byTmp = lpszInStr[i] & 0x0f;
    if (l_byTmp < 10)
      lpszHex[j++] = l_byTmp + '0';
    else
      lpszHex[j++] = l_byTmp - 10 + 'A';
  }
  lpszHex[j] = 0;
  return;
}


x86 assembly (clang, -O0):
<HexToStr>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x20(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1207 <HexToStr+0x107>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xf0,%eax
sar    $0x4,%eax
mov    %al,-0x21(%rbp)
movsbl -0x21(%rbp),%eax
cmp    $0xa,%eax
jge    1170 <HexToStr+0x70>
movsbl -0x21(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x20(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1191 <HexToStr+0x91>
movsbl -0x21(%rbp),%eax
sub    $0xa,%eax
add    $0x41,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x20(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xf,%eax
mov    %al,-0x21(%rbp)
movsbl -0x21(%rbp),%eax
cmp    $0xa,%eax
jge    11d3 <HexToStr+0xd3>
movsbl -0x21(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x20(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11f4 <HexToStr+0xf4>
movsbl -0x21(%rbp),%eax
sub    $0xa,%eax
add    $0x41,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x20(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11f9 <HexToStr+0xf9>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    111d <HexToStr+0x1d>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<HexToStr>:
test   %esi,%esi
jle    1185 <HexToStr+0x85>
mov    %esi,%r8d
cmp    $0x8,%esi
jb     1122 <HexToStr+0x22>
lea    (%rdi,%r8,1),%rax
cmp    %rdx,%rax
jbe    118e <HexToStr+0x8e>
lea    (%rdx,%r8,2),%rax
cmp    %rdi,%rax
jbe    118e <HexToStr+0x8e>
xor    %r10d,%r10d
xor    %r9d,%r9d
nopl   0x0(%rax,%rax,1)
movzbl (%rdi,%r10,1),%eax
mov    %eax,%ecx
shr    $0x4,%cl
lea    0x30(%rcx),%esi
add    $0x37,%cl
cmp    $0xa0,%al
movzbl %sil,%eax
movzbl %cl,%ecx
cmovb  %eax,%ecx
mov    %cl,(%rdx,%r9,1)
movzbl (%rdi,%r10,1),%eax
and    $0xf,%al
lea    0x30(%rax),%ecx
lea    0x37(%rax),%esi
cmp    $0xa,%al
movzbl %cl,%eax
movzbl %sil,%ecx
cmovb  %eax,%ecx
mov    %cl,0x1(%rdx,%r9,1)
add    $0x2,%r9
add    $0x1,%r10
cmp    %r10,%r8
jne    1130 <HexToStr+0x30>
and    $0xfffffffe,%r9d
movb   $0x0,(%rdx,%r9,1)
ret
xor    %r9d,%r9d
movb   $0x0,(%rdx,%r9,1)
ret
mov    %r8d,%r10d
and    $0xfffffff8,%r10d
lea    (%r10,%r10,1),%r9
xor    %eax,%eax
movdqa 0xe5c(%rip),%xmm8
movdqa 0xe63(%rip),%xmm9
movdqa 0xe6b(%rip),%xmm2
movdqa 0xe73(%rip),%xmm3
movdqa 0xe7b(%rip),%xmm4
movdqa 0xe83(%rip),%xmm5
nopl   (%rax)
movq   (%rdi,%rax,1),%xmm6
movdqa %xmm6,%xmm7
psrlw  $0x4,%xmm7
pand   %xmm8,%xmm7
movdqa %xmm6,%xmm0
pmaxub %xmm9,%xmm0
pcmpeqb %xmm6,%xmm0
movdqa %xmm7,%xmm1
por    %xmm2,%xmm1
paddb  %xmm3,%xmm7
pand   %xmm0,%xmm7
pandn  %xmm1,%xmm0
por    %xmm7,%xmm0
pand   %xmm4,%xmm6
movdqa %xmm6,%xmm1
pmaxub %xmm5,%xmm1
pcmpeqb %xmm6,%xmm1
movdqa %xmm6,%xmm7
por    %xmm2,%xmm7
paddb  %xmm3,%xmm6
pand   %xmm1,%xmm6
pandn  %xmm7,%xmm1
por    %xmm6,%xmm1
punpcklbw %xmm1,%xmm0
movdqu %xmm0,(%rdx,%rax,2)
add    $0x8,%rax
cmp    %rax,%r10
jne    11d0 <HexToStr+0xd0>
cmp    %r8,%r10
jne    1130 <HexToStr+0x30>
jmp    117b <HexToStr+0x7b>

LLVM IR (-O0):
define void @HexToStr(i8* %0, i32 %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8
store i8* %0, i8** %4
store i32 %1, i32* %5
store i8* %2, i8** %6
store i32 0, i32* %8
store i32 0, i32* %7
br label %10
10: ; preds = %82, %3
%11 = load i32, i32* %7
%12 = load i32, i32* %5
%13 = icmp slt i32 %11, %12
br i1 %13, label %14, label %85
14: ; preds = %10
%15 = load i8*, i8** %4
%16 = load i32, i32* %7
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %15, i64 %17
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = and i32 %20, 240
%22 = ashr i32 %21, 4
%23 = trunc i32 %22 to i8
store i8 %23, i8* %9
%24 = load i8, i8* %9
%25 = sext i8 %24 to i32
%26 = icmp slt i32 %25, 10
br i1 %26, label %27, label %37
27: ; preds = %14
%28 = load i8, i8* %9
%29 = sext i8 %28 to i32
%30 = add nsw i32 %29, 48
%31 = trunc i32 %30 to i8
%32 = load i8*, i8** %6
%33 = load i32, i32* %8
%34 = add nsw i32 %33, 1
store i32 %34, i32* %8
%35 = sext i32 %33 to i64
%36 = getelementptr inbounds i8, i8* %32, i64 %35
store i8 %31, i8* %36
br label %48
37: ; preds = %14
%38 = load i8, i8* %9
%39 = sext i8 %38 to i32
%40 = sub nsw i32 %39, 10
%41 = add nsw i32 %40, 65
%42 = trunc i32 %41 to i8
%43 = load i8*, i8** %6
%44 = load i32, i32* %8
%45 = add nsw i32 %44, 1
store i32 %45, i32* %8
%46 = sext i32 %44 to i64
%47 = getelementptr inbounds i8, i8* %43, i64 %46
store i8 %42, i8* %47
br label %48
48: ; preds = %37, %27
%49 = load i8*, i8** %4
%50 = load i32, i32* %7
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds i8, i8* %49, i64 %51
%53 = load i8, i8* %52
%54 = sext i8 %53 to i32
%55 = and i32 %54, 15
%56 = trunc i32 %55 to i8
store i8 %56, i8* %9
%57 = load i8, i8* %9
%58 = sext i8 %57 to i32
%59 = icmp slt i32 %58, 10
br i1 %59, label %60, label %70
60: ; preds = %48
%61 = load i8, i8* %9
%62 = sext i8 %61 to i32
%63 = add nsw i32 %62, 48
%64 = trunc i32 %63 to i8
%65 = load i8*, i8** %6
%66 = load i32, i32* %8
%67 = add nsw i32 %66, 1
store i32 %67, i32* %8
%68 = sext i32 %66 to i64
%69 = getelementptr inbounds i8, i8* %65, i64 %68
store i8 %64, i8* %69
br label %81
70: ; preds = %48
%71 = load i8, i8* %9
%72 = sext i8 %71 to i32
%73 = sub nsw i32 %72, 10
%74 = add nsw i32 %73, 65
%75 = trunc i32 %74 to i8
%76 = load i8*, i8** %6
%77 = load i32, i32* %8
%78 = add nsw i32 %77, 1
store i32 %78, i32* %8
%79 = sext i32 %77 to i64
%80 = getelementptr inbounds i8, i8* %76, i64 %79
store i8 %75, i8* %80
br label %81
81: ; preds = %70, %60
br label %82
82: ; preds = %81
%83 = load i32, i32* %7
%84 = add nsw i32 %83, 1
store i32 %84, i32* %7
br label %10
85: ; preds = %10
%86 = load i8*, i8** %6
%87 = load i32, i32* %8
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds i8, i8* %86, i64 %88
store i8 0, i8* %89
ret void
}

LLVM IR (-O2):
define void @HexToStr(i8* nocapture %0, i32 %1, i8* nocapture writeonly %2) {
%4 = icmp sgt i32 %1, 0
br i1 %4, label %5, label %73
5: ; preds = %3
%6 = zext i32 %1 to i64
%7 = icmp ult i32 %1, 8
br i1 %7, label %45, label %8
8: ; preds = %5
%9 = shl nuw nsw i64 %6, 1
%10 = getelementptr i8, i8* %2, i64 %9
%11 = getelementptr i8, i8* %0, i64 %6
%12 = icmp ugt i8* %11, %2
%13 = icmp ugt i8* %10, %0
%14 = and i1 %12, %13
br i1 %14, label %45, label %15
15: ; preds = %8
%16 = and i64 %6, 4294967288
%17 = shl nuw nsw i64 %16, 1
%18 = getelementptr inbounds i8, i8* %2, i64 -1
br label %19
19: ; preds = %19, %15
%20 = phi i64 [ 0, %15 ], [ %41, %19 ]
%21 = shl i64 %20, 1
%22 = getelementptr inbounds i8, i8* %0, i64 %20
%23 = bitcast i8* %22 to <8 x i8>*
%24 = load <8 x i8>, <8 x i8>* %23
%25 = lshr <8 x i8> %24, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%26 = icmp ult <8 x i8> %24, <i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96, i8 -96>
%27 = or <8 x i8> %25, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%28 = add nuw nsw <8 x i8> %25, <i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55>
%29 = select <8 x i1> %26, <8 x i8> %27, <8 x i8> %28
%30 = or i64 %21, 1
%31 = bitcast i8* %22 to <8 x i8>*
%32 = load <8 x i8>, <8 x i8>* %31
%33 = and <8 x i8> %32, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%34 = icmp ult <8 x i8> %33, <i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10>
%35 = or <8 x i8> %33, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%36 = add nuw nsw <8 x i8> %33, <i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55>
%37 = select <8 x i1> %34, <8 x i8> %35, <8 x i8> %36
%38 = getelementptr inbounds i8, i8* %18, i64 %30
%39 = bitcast i8* %38 to <16 x i8>*
%40 = shufflevector <8 x i8> %29, <8 x i8> %37, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
store <16 x i8> %40, <16 x i8>* %39
%41 = add nuw i64 %20, 8
%42 = icmp eq i64 %41, %16
br i1 %42, label %43, label %19
43: ; preds = %19
%44 = icmp eq i64 %16, %6
br i1 %44, label %70, label %45
45: ; preds = %8, %5, %43
%46 = phi i64 [ 0, %8 ], [ 0, %5 ], [ %16, %43 ]
%47 = phi i64 [ 0, %8 ], [ 0, %5 ], [ %17, %43 ]
br label %48
48: ; preds = %45, %48
%49 = phi i64 [ %68, %48 ], [ %46, %45 ]
%50 = phi i64 [ %67, %48 ], [ %47, %45 ]
%51 = getelementptr inbounds i8, i8* %0, i64 %49
%52 = load i8, i8* %51
%53 = lshr i8 %52, 4
%54 = icmp ult i8 %52, -96
%55 = or i8 %53, 48
%56 = add nuw nsw i8 %53, 55
%57 = select i1 %54, i8 %55, i8 %56
%58 = getelementptr inbounds i8, i8* %2, i64 %50
store i8 %57, i8* %58
%59 = or i64 %50, 1
%60 = load i8, i8* %51
%61 = and i8 %60, 15
%62 = icmp ult i8 %61, 10
%63 = or i8 %61, 48
%64 = add nuw nsw i8 %61, 55
%65 = select i1 %62, i8 %63, i8 %64
%66 = getelementptr inbounds i8, i8* %2, i64 %59
store i8 %65, i8* %66
%67 = add nuw nsw i64 %50, 2
%68 = add nuw nsw i64 %49, 1
%69 = icmp eq i64 %68, %6
br i1 %69, label %70, label %48
70: ; preds = %48, %43
%71 = phi i64 [ %17, %43 ], [ %67, %48 ]
%72 = and i64 %71, 4294967294
br label %73
73: ; preds = %70, %3
%74 = phi i64 [ 0, %3 ], [ %72, %70 ]
%75 = getelementptr inbounds i8, i8* %2, i64 %74
store i8 0, i8* %75
ret void
}