void BcdToAsciiString(unsigned char *pBcd, unsigned char *pAscii,
                      unsigned int size) {
  unsigned int i;
  unsigned char vNible;
  for (i = 0; i < size; i++) {
    vNible = (((*pBcd) & 0xF0) >> 4) | 0x30;
    *pAscii++ = vNible;
    vNible = ((*pBcd) & 0x0F) | 0x30;
    *pAscii++ = vNible;
    pBcd++;
  }
}


x86 assembly (clang, -O0):
<BcdToAsciiString>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jae    1189 <BcdToAsciiString+0x89>
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
and    $0xf0,%eax
sar    $0x4,%eax
or     $0x30,%eax
mov    %al,-0x19(%rbp)
mov    -0x19(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
and    $0xf,%eax
or     $0x30,%eax
mov    %al,-0x19(%rbp)
mov    -0x19(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1116 <BcdToAsciiString+0x16>
pop    %rbp
ret

x86 assembly (clang, -O2):
<BcdToAsciiString>:
test   %edx,%edx
je     12a1 <BcdToAsciiString+0x1a1>
lea    -0x1(%rdx),%r10d
xor    %r8d,%r8d
cmp    $0x7,%r10d
jb     1227 <BcdToAsciiString+0x127>
lea    (%r10,%rdi,1),%rax
add    $0x1,%rax
cmp    %rsi,%rax
jbe    1137 <BcdToAsciiString+0x37>
lea    (%rsi,%r10,2),%rax
add    $0x2,%rax
cmp    %rdi,%rax
ja     1227 <BcdToAsciiString+0x127>
add    $0x1,%r10
mov    %r10,%r8
and    $0xfffffffffffffff8,%r8
lea    -0x8(%r8),%rax
mov    %rax,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rax,%rax
je     12a2 <BcdToAsciiString+0x1a2>
mov    %r9,%rcx
and    $0xfffffffffffffffe,%rcx
xor    %eax,%eax
movdqa 0xe95(%rip),%xmm0
movdqa 0xe9d(%rip),%xmm1
movdqa 0xea5(%rip),%xmm2
nopl   0x0(%rax,%rax,1)
movq   (%rdi,%rax,1),%xmm3
movdqa %xmm3,%xmm4
psrlw  $0x4,%xmm4
pand   %xmm0,%xmm4
por    %xmm1,%xmm4
pand   %xmm2,%xmm3
por    %xmm1,%xmm3
punpcklbw %xmm3,%xmm4
movdqu %xmm4,(%rsi,%rax,2)
movq   0x8(%rdi,%rax,1),%xmm3
movdqa %xmm3,%xmm4
psrlw  $0x4,%xmm4
pand   %xmm0,%xmm4
por    %xmm1,%xmm4
pand   %xmm2,%xmm3
por    %xmm1,%xmm3
punpcklbw %xmm3,%xmm4
movdqu %xmm4,0x10(%rsi,%rax,2)
add    $0x10,%rax
add    $0xfffffffffffffffe,%rcx
jne    1180 <BcdToAsciiString+0x80>
test   $0x1,%r9b
je     1217 <BcdToAsciiString+0x117>
movq   (%rdi,%rax,1),%xmm0
movdqa %xmm0,%xmm1
psrlw  $0x4,%xmm1
pand   0xe0a(%rip),%xmm1
movdqa 0xe12(%rip),%xmm2
pand   0xe1a(%rip),%xmm0
por    %xmm2,%xmm1
por    %xmm2,%xmm0
punpcklbw %xmm0,%xmm1
movdqu %xmm1,(%rsi,%rax,2)
cmp    %r8,%r10
je     12a1 <BcdToAsciiString+0x1a1>
add    %r8,%rdi
lea    (%rsi,%r8,2),%rsi
mov    %edx,%ecx
sub    %r8d,%ecx
mov    %r8d,%eax
not    %eax
test   $0x1,%cl
je     1257 <BcdToAsciiString+0x157>
mov    (%rdi),%cl
shr    $0x4,%cl
or     $0x30,%cl
mov    %cl,(%rsi)
mov    (%rdi),%cl
and    $0xf,%cl
or     $0x30,%cl
mov    %cl,0x1(%rsi)
add    $0x2,%rsi
add    $0x1,%rdi
add    $0x1,%r8d
add    %edx,%eax
je     12a1 <BcdToAsciiString+0x1a1>
sub    %r8d,%edx
xor    %eax,%eax
movzbl (%rdi,%rax,1),%ecx
shr    $0x4,%cl
or     $0x30,%cl
mov    %cl,(%rsi,%rax,2)
movzbl (%rdi,%rax,1),%ecx
and    $0xf,%cl
or     $0x30,%cl
mov    %cl,0x1(%rsi,%rax,2)
movzbl 0x1(%rdi,%rax,1),%ecx
shr    $0x4,%cl
or     $0x30,%cl
mov    %cl,0x2(%rsi,%rax,2)
movzbl 0x1(%rdi,%rax,1),%ecx
and    $0xf,%cl
or     $0x30,%cl
mov    %cl,0x3(%rsi,%rax,2)
add    $0x2,%rax
cmp    %eax,%edx
jne    1260 <BcdToAsciiString+0x160>
ret
xor    %eax,%eax
test   $0x1,%r9b
jne    11e0 <BcdToAsciiString+0xe0>
jmp    1217 <BcdToAsciiString+0x117>

LLVM IR (-O0):
define void @BcdToAsciiString(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i8
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
store i32 0, i32* %7
br label %9
9: ; preds = %35, %3
%10 = load i32, i32* %7
%11 = load i32, i32* %6
%12 = icmp ult i32 %10, %11
br i1 %12, label %13, label %38
13: ; preds = %9
%14 = load i8*, i8** %4
%15 = load i8, i8* %14
%16 = zext i8 %15 to i32
%17 = and i32 %16, 240
%18 = ashr i32 %17, 4
%19 = or i32 %18, 48
%20 = trunc i32 %19 to i8
store i8 %20, i8* %8
%21 = load i8, i8* %8
%22 = load i8*, i8** %5
%23 = getelementptr inbounds i8, i8* %22, i32 1
store i8* %23, i8** %5
store i8 %21, i8* %22
%24 = load i8*, i8** %4
%25 = load i8, i8* %24
%26 = zext i8 %25 to i32
%27 = and i32 %26, 15
%28 = or i32 %27, 48
%29 = trunc i32 %28 to i8
store i8 %29, i8* %8
%30 = load i8, i8* %8
%31 = load i8*, i8** %5
%32 = getelementptr inbounds i8, i8* %31, i32 1
store i8* %32, i8** %5
store i8 %30, i8* %31
%33 = load i8*, i8** %4
%34 = getelementptr inbounds i8, i8* %33, i32 1
store i8* %34, i8** %4
br label %35
35: ; preds = %13
%36 = load i32, i32* %7
%37 = add i32 %36, 1
store i32 %37, i32* %7
br label %9
38: ; preds = %9
ret void
}

LLVM IR (-O2):
define void @BcdToAsciiString(i8* nocapture %0, i8* nocapture writeonly %1, i32 %2) {
%4 = icmp eq i32 %2, 0
br i1 %4, label %129, label %5
5: ; preds = %3
%6 = add i32 %2, -1
%7 = zext i32 %6 to i64
%8 = add nuw nsw i64 %7, 1
%9 = icmp ult i32 %6, 7
br i1 %9, label %80, label %10
10: ; preds = %5
%11 = add i32 %2, -1
%12 = zext i32 %11 to i64
%13 = shl nuw nsw i64 %12, 1
%14 = add nuw nsw i64 %13, 2
%15 = getelementptr i8, i8* %1, i64 %14
%16 = add nuw nsw i64 %12, 1
%17 = getelementptr i8, i8* %0, i64 %16
%18 = icmp ugt i8* %17, %1
%19 = icmp ugt i8* %15, %0
%20 = and i1 %18, %19
br i1 %20, label %80, label %21
21: ; preds = %10
%22 = and i64 %8, 8589934584
%23 = getelementptr i8, i8* %0, i64 %22
%24 = trunc i64 %22 to i32
%25 = shl nuw nsw i64 %22, 1
%26 = getelementptr i8, i8* %1, i64 %25
%27 = add nsw i64 %22, -8
%28 = lshr exact i64 %27, 3
%29 = add nuw nsw i64 %28, 1
%30 = and i64 %29, 1
%31 = icmp eq i64 %27, 0
br i1 %31, label %63, label %32
32: ; preds = %21
%33 = and i64 %29, 4611686018427387902
br label %34
34: ; preds = %34, %32
%35 = phi i64 [ 0, %32 ], [ %60, %34 ]
%36 = phi i64 [ 0, %32 ], [ %61, %34 ]
%37 = getelementptr i8, i8* %0, i64 %35
%38 = shl i64 %35, 1
%39 = bitcast i8* %37 to <8 x i8>*
%40 = load <8 x i8>, <8 x i8>* %39
%41 = lshr <8 x i8> %40, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%42 = or <8 x i8> %41, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%43 = and <8 x i8> %40, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%44 = or <8 x i8> %43, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%45 = getelementptr inbounds i8, i8* %1, i64 %38
%46 = bitcast i8* %45 to <16 x i8>*
%47 = shufflevector <8 x i8> %42, <8 x i8> %44, <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> %47, <16 x i8>* %46
%48 = or i64 %35, 8
%49 = getelementptr i8, i8* %0, i64 %48
%50 = shl i64 %48, 1
%51 = bitcast i8* %49 to <8 x i8>*
%52 = load <8 x i8>, <8 x i8>* %51
%53 = lshr <8 x i8> %52, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%54 = or <8 x i8> %53, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%55 = and <8 x i8> %52, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%56 = or <8 x i8> %55, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%57 = getelementptr inbounds i8, i8* %1, i64 %50
%58 = bitcast i8* %57 to <16 x i8>*
%59 = shufflevector <8 x i8> %54, <8 x i8> %56, <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> %59, <16 x i8>* %58
%60 = add nuw i64 %35, 16
%61 = add i64 %36, 2
%62 = icmp eq i64 %61, %33
br i1 %62, label %63, label %34
63: ; preds = %34, %21
%64 = phi i64 [ 0, %21 ], [ %60, %34 ]
%65 = icmp eq i64 %30, 0
br i1 %65, label %78, label %66
66: ; preds = %63
%67 = getelementptr i8, i8* %0, i64 %64
%68 = shl i64 %64, 1
%69 = bitcast i8* %67 to <8 x i8>*
%70 = load <8 x i8>, <8 x i8>* %69
%71 = lshr <8 x i8> %70, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%72 = or <8 x i8> %71, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%73 = and <8 x i8> %70, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%74 = or <8 x i8> %73, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%75 = getelementptr inbounds i8, i8* %1, i64 %68
%76 = bitcast i8* %75 to <16 x i8>*
%77 = shufflevector <8 x i8> %72, <8 x i8> %74, <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> %77, <16 x i8>* %76
br label %78
78: ; preds = %63, %66
%79 = icmp eq i64 %8, %22
br i1 %79, label %129, label %80
80: ; preds = %10, %5, %78
%81 = phi i8* [ %0, %10 ], [ %0, %5 ], [ %23, %78 ]
%82 = phi i32 [ 0, %10 ], [ 0, %5 ], [ %24, %78 ]
%83 = phi i8* [ %1, %10 ], [ %1, %5 ], [ %26, %78 ]
%84 = sub i32 %2, %82
%85 = xor i32 %82, -1
%86 = and i32 %84, 1
%87 = icmp eq i32 %86, 0
br i1 %87, label %99, label %88
88: ; preds = %80
%89 = load i8, i8* %81
%90 = lshr i8 %89, 4
%91 = or i8 %90, 48
%92 = getelementptr inbounds i8, i8* %83, i64 1
store i8 %91, i8* %83
%93 = load i8, i8* %81
%94 = and i8 %93, 15
%95 = or i8 %94, 48
%96 = getelementptr inbounds i8, i8* %83, i64 2
store i8 %95, i8* %92
%97 = getelementptr inbounds i8, i8* %81, i64 1
%98 = add nuw i32 %82, 1
br label %99
99: ; preds = %88, %80
%100 = phi i8* [ %81, %80 ], [ %97, %88 ]
%101 = phi i32 [ %82, %80 ], [ %98, %88 ]
%102 = phi i8* [ %83, %80 ], [ %96, %88 ]
%103 = sub i32 0, %2
%104 = icmp eq i32 %85, %103
br i1 %104, label %129, label %105
105: ; preds = %99, %105
%106 = phi i8* [ %126, %105 ], [ %100, %99 ]
%107 = phi i32 [ %127, %105 ], [ %101, %99 ]
%108 = phi i8* [ %125, %105 ], [ %102, %99 ]
%109 = load i8, i8* %106
%110 = lshr i8 %109, 4
%111 = or i8 %110, 48
%112 = getelementptr inbounds i8, i8* %108, i64 1
store i8 %111, i8* %108
%113 = load i8, i8* %106
%114 = and i8 %113, 15
%115 = or i8 %114, 48
%116 = getelementptr inbounds i8, i8* %108, i64 2
store i8 %115, i8* %112
%117 = getelementptr inbounds i8, i8* %106, i64 1
%118 = load i8, i8* %117
%119 = lshr i8 %118, 4
%120 = or i8 %119, 48
%121 = getelementptr inbounds i8, i8* %108, i64 3
store i8 %120, i8* %116
%122 = load i8, i8* %117
%123 = and i8 %122, 15
%124 = or i8 %123, 48
%125 = getelementptr inbounds i8, i8* %108, i64 4
store i8 %124, i8* %121
%126 = getelementptr inbounds i8, i8* %106, i64 2
%127 = add nuw i32 %107, 2
%128 = icmp eq i32 %127, %2
br i1 %128, label %129, label %105
129: ; preds = %99, %105, %78, %3
ret void
}