void UART_putnum(unsigned int num, unsigned char deel, char teken) {
  static unsigned char chars[17] = "0123456789ABCDEF";
  unsigned int rest;
  signed char c[16];
  signed int i = 15;
  if (num == 0) {
    c[i] = '0';
    i--;
  } else {
    while (num > 0) {
      rest = num % deel;
      num /= deel;
      c[i] = chars[rest];
      i--;
      if (i == 0)
        num = 0;
    }
    if (teken == 1) {
      c[i] = '-';
      i--;
    }
  }
  while (!((*((volatile unsigned char *)0xE000C014)) & (1 << 6)))
    ;
  while (i < 15) {
    i++;
    (*((volatile unsigned char *)0xE000C000)) = c[i];
  }
}


x86 assembly (clang, -O0):
<UART_putnum>:
push   %rbp
mov    %rsp,%rbp
mov    %dl,%al
mov    %sil,%cl
mov    %edi,-0x4(%rbp)
mov    %cl,-0x5(%rbp)
mov    %al,-0x6(%rbp)
movl   $0xf,-0x24(%rbp)
cmpl   $0x0,-0x4(%rbp)
jne    113a <UART_putnum+0x3a>
movslq -0x24(%rbp),%rax
movb   $0x30,-0x20(%rbp,%rax,1)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    11bf <UART_putnum+0xbf>
jmp    113f <UART_putnum+0x3f>
cmpl   $0x0,-0x4(%rbp)
jbe    119b <UART_putnum+0x9b>
mov    -0x4(%rbp),%eax
movzbl -0x5(%rbp),%ecx
xor    %edx,%edx
div    %ecx
mov    %edx,-0xc(%rbp)
movzbl -0x5(%rbp),%ecx
mov    -0x4(%rbp),%eax
xor    %edx,%edx
div    %ecx
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,%ecx
lea    0x2ebf(%rip),%rax
mov    (%rax,%rcx,1),%cl
movslq -0x24(%rbp),%rax
mov    %cl,-0x20(%rbp,%rax,1)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
cmpl   $0x0,-0x24(%rbp)
jne    1196 <UART_putnum+0x96>
movl   $0x0,-0x4(%rbp)
jmp    113f <UART_putnum+0x3f>
movsbl -0x6(%rbp),%eax
cmp    $0x1,%eax
jne    11ba <UART_putnum+0xba>
movslq -0x24(%rbp),%rax
movb   $0x2d,-0x20(%rbp,%rax,1)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    11bf <UART_putnum+0xbf>
jmp    11c4 <UART_putnum+0xc4>
mov    $0xe000c014,%eax
mov    (%rax),%al
movzbl %al,%eax
and    $0x40,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    11e6 <UART_putnum+0xe6>
jmp    11eb <UART_putnum+0xeb>
jmp    11c4 <UART_putnum+0xc4>
jmp    11f0 <UART_putnum+0xf0>
cmpl   $0xf,-0x24(%rbp)
jge    1217 <UART_putnum+0x117>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
movslq -0x24(%rbp),%rax
mov    -0x20(%rbp,%rax,1),%cl
mov    $0xe000c000,%eax
mov    %cl,(%rax)
jmp    11f0 <UART_putnum+0xf0>
pop    %rbp
ret

x86 assembly (clang, -O2):
<UART_putnum>:
push   %rbx
test   %edi,%edi
je     1171 <UART_putnum+0x71>
mov    %edx,%r8d
mov    %edi,%eax
movzbl %sil,%r9d
mov    $0xf,%edi
mov    $0xe,%esi
movabs $0xf00000000,%rcx
xor    %r10d,%r10d
lea    0xed4(%rip),%r11
movabs $0xffffffff00000000,%rbx
ff ff ff
cs nopw 0x0(%rax,%rax,1)
xor    %edx,%edx
div    %r9d
movzbl (%rdx,%r11,1),%edx
mov    %dl,-0x10(%rsp,%rdi,1)
add    $0xffffffffffffffff,%rdi
sub    $0x1,%esi
cmovb  %r10d,%eax
add    %rbx,%rcx
test   %eax,%eax
jne    1140 <UART_putnum+0x40>
cmp    $0x1,%r8b
jne    117d <UART_putnum+0x7d>
sar    $0x20,%rcx
movb   $0x2d,-0x10(%rsp,%rcx,1)
jmp    117f <UART_putnum+0x7f>
movb   $0x30,-0x1(%rsp)
mov    $0xe,%esi
jmp    117f <UART_putnum+0x7f>
mov    %edi,%esi
mov    $0xe000c000,%eax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
testb  $0x40,0x14(%rax)
je     1190 <UART_putnum+0x90>
cmp    $0xe,%esi
jg     1222 <UART_putnum+0x122>
movslq %esi,%rdx
mov    $0x7,%edi
sub    %esi,%edi
mov    %rdx,%rcx
and    $0x7,%rdi
je     11d1 <UART_putnum+0xd1>
mov    %rdx,%rcx
cs nopw 0x0(%rax,%rax,1)
nop
movzbl -0xf(%rsp,%rcx,1),%ebx
add    $0x1,%rcx
mov    %bl,(%rax)
add    $0xffffffffffffffff,%rdi
jne    11c0 <UART_putnum+0xc0>
add    $0xfffffffffffffff8,%rdx
cmp    $0x7,%rdx
jb     1222 <UART_putnum+0x122>
nopl   0x0(%rax,%rax,1)
movzbl -0xf(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0xe(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0xd(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0xc(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0xb(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0xa(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0x9(%rsp,%rcx,1),%edx
mov    %dl,(%rax)
movzbl -0x8(%rsp,%rcx,1),%edx
add    $0x8,%rcx
mov    %dl,(%rax)
cmp    $0xf,%rcx
jne    11e0 <UART_putnum+0xe0>
pop    %rbx
ret

LLVM IR (-O0):
@UART_putnum.chars = internal global [17 x i8] c"0123456789ABCDEF\00"
define void @UART_putnum(i32 %0, i8 zeroext %1, i8 signext %2) {
%4 = alloca i32
%5 = alloca i8
%6 = alloca i8
%7 = alloca i32
%8 = alloca [16 x i8]
%9 = alloca i32
store i32 %0, i32* %4
store i8 %1, i8* %5
store i8 %2, i8* %6
store i32 15, i32* %9
%10 = load i32, i32* %4
%11 = icmp eq i32 %10, 0
br i1 %11, label %12, label %18
12: ; preds = %3
%13 = load i32, i32* %9
%14 = sext i32 %13 to i64
%15 = getelementptr inbounds [16 x i8], [16 x i8]* %8, i64 0, i64 %14
store i8 48, i8* %15
%16 = load i32, i32* %9
%17 = add nsw i32 %16, -1
store i32 %17, i32* %9
br label %55
18: ; preds = %3
br label %19
19: ; preds = %43, %18
%20 = load i32, i32* %4
%21 = icmp ugt i32 %20, 0
br i1 %21, label %22, label %44
22: ; preds = %19
%23 = load i32, i32* %4
%24 = load i8, i8* %5
%25 = zext i8 %24 to i32
%26 = urem i32 %23, %25
store i32 %26, i32* %7
%27 = load i8, i8* %5
%28 = zext i8 %27 to i32
%29 = load i32, i32* %4
%30 = udiv i32 %29, %28
store i32 %30, i32* %4
%31 = load i32, i32* %7
%32 = zext i32 %31 to i64
%33 = getelementptr inbounds [17 x i8], [17 x i8]* @UART_putnum.chars, i64 0, i64 %32
%34 = load i8, i8* %33
%35 = load i32, i32* %9
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds [16 x i8], [16 x i8]* %8, i64 0, i64 %36
store i8 %34, i8* %37
%38 = load i32, i32* %9
%39 = add nsw i32 %38, -1
store i32 %39, i32* %9
%40 = load i32, i32* %9
%41 = icmp eq i32 %40, 0
br i1 %41, label %42, label %43
42: ; preds = %22
store i32 0, i32* %4
br label %43
43: ; preds = %42, %22
br label %19
44: ; preds = %19
%45 = load i8, i8* %6
%46 = sext i8 %45 to i32
%47 = icmp eq i32 %46, 1
br i1 %47, label %48, label %54
48: ; preds = %44
%49 = load i32, i32* %9
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds [16 x i8], [16 x i8]* %8, i64 0, i64 %50
store i8 45, i8* %51
%52 = load i32, i32* %9
%53 = add nsw i32 %52, -1
store i32 %53, i32* %9
br label %54
54: ; preds = %48, %44
br label %55
55: ; preds = %54, %12
br label %56
56: ; preds = %62, %55
%57 = load volatile i8, i8* inttoptr (i64 3758145556 to i8*)
%58 = zext i8 %57 to i32
%59 = and i32 %58, 64
%60 = icmp ne i32 %59, 0
%61 = xor i1 %60, true
br i1 %61, label %62, label %63
62: ; preds = %56
br label %56
63: ; preds = %56
br label %64
64: ; preds = %67, %63
%65 = load i32, i32* %9
%66 = icmp slt i32 %65, 15
br i1 %66, label %67, label %74
67: ; preds = %64
%68 = load i32, i32* %9
%69 = add nsw i32 %68, 1
store i32 %69, i32* %9
%70 = load i32, i32* %9
%71 = sext i32 %70 to i64
%72 = getelementptr inbounds [16 x i8], [16 x i8]* %8, i64 0, i64 %71
%73 = load i8, i8* %72
store volatile i8 %73, i8* inttoptr (i64 3758145536 to i8*)
br label %64
74: ; preds = %64
ret void
}

LLVM IR (-O2):
@UART_putnum.chars = internal unnamed_addr constant [17 x i8] c"0123456789ABCDEF\00"
define void @UART_putnum(i32 %0, i8 zeroext %1, i8 signext %2) {
%4 = alloca [16 x i8]
%5 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 0
%6 = icmp eq i32 %0, 0
br i1 %6, label %9, label %7
7: ; preds = %3
%8 = zext i8 %1 to i32
br label %11
9: ; preds = %3
%10 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 15
store i8 48, i8* %10
br label %34
11: ; preds = %7, %11
%12 = phi i64 [ 15, %7 ], [ %20, %11 ]
%13 = phi i32 [ %0, %7 ], [ %23, %11 ]
%14 = urem i32 %13, %8
%15 = udiv i32 %13, %8
%16 = zext i32 %14 to i64
%17 = getelementptr inbounds [17 x i8], [17 x i8]* @UART_putnum.chars, i64 0, i64 %16
%18 = load i8, i8* %17
%19 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %12
store i8 %18, i8* %19
%20 = add i64 %12, -1
%21 = trunc i64 %20 to i32
%22 = icmp eq i32 %21, 0
%23 = select i1 %22, i32 0, i32 %15
%24 = icmp eq i32 %23, 0
br i1 %24, label %25, label %11
25: ; preds = %11
%26 = trunc i64 %20 to i32
%27 = icmp eq i8 %2, 1
br i1 %27, label %28, label %34
28: ; preds = %25
%29 = trunc i64 %12 to i32
%30 = shl i64 %20, 32
%31 = ashr exact i64 %30, 32
%32 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %31
store i8 45, i8* %32
%33 = add nsw i32 %29, -2
br label %34
34: ; preds = %25, %28, %9
%35 = phi i32 [ 14, %9 ], [ %33, %28 ], [ %26, %25 ]
br label %36
36: ; preds = %36, %34
%37 = load volatile i8, i8* inttoptr (i64 3758145556 to i8*)
%38 = and i8 %37, 64
%39 = icmp eq i8 %38, 0
br i1 %39, label %36, label %40
40: ; preds = %36
%41 = icmp slt i32 %35, 15
br i1 %41, label %42, label %86
42: ; preds = %40
%43 = sext i32 %35 to i64
%44 = sub nsw i64 7, %43
%45 = and i64 %44, 7
%46 = icmp eq i64 %45, 0
br i1 %46, label %55, label %47
47: ; preds = %42, %47
%48 = phi i64 [ %50, %47 ], [ %43, %42 ]
%49 = phi i64 [ %53, %47 ], [ 0, %42 ]
%50 = add nsw i64 %48, 1
%51 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %50
%52 = load i8, i8* %51
store volatile i8 %52, i8* inttoptr (i64 3758145536 to i8*)
%53 = add i64 %49, 1
%54 = icmp eq i64 %53, %45
br i1 %54, label %55, label %47
55: ; preds = %47, %42
%56 = phi i64 [ %43, %42 ], [ %50, %47 ]
%57 = add nsw i64 %43, -8
%58 = icmp ult i64 %57, 7
br i1 %58, label %86, label %59
59: ; preds = %55, %59
%60 = phi i64 [ %82, %59 ], [ %56, %55 ]
%61 = add nsw i64 %60, 1
%62 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %61
%63 = load i8, i8* %62
store volatile i8 %63, i8* inttoptr (i64 3758145536 to i8*)
%64 = add nsw i64 %60, 2
%65 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %64
%66 = load i8, i8* %65
store volatile i8 %66, i8* inttoptr (i64 3758145536 to i8*)
%67 = add nsw i64 %60, 3
%68 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %67
%69 = load i8, i8* %68
store volatile i8 %69, i8* inttoptr (i64 3758145536 to i8*)
%70 = add nsw i64 %60, 4
%71 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %70
%72 = load i8, i8* %71
store volatile i8 %72, i8* inttoptr (i64 3758145536 to i8*)
%73 = add nsw i64 %60, 5
%74 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %73
%75 = load i8, i8* %74
store volatile i8 %75, i8* inttoptr (i64 3758145536 to i8*)
%76 = add nsw i64 %60, 6
%77 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %76
%78 = load i8, i8* %77
store volatile i8 %78, i8* inttoptr (i64 3758145536 to i8*)
%79 = add nsw i64 %60, 7
%80 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %79
%81 = load i8, i8* %80
store volatile i8 %81, i8* inttoptr (i64 3758145536 to i8*)
%82 = add nsw i64 %60, 8
%83 = getelementptr inbounds [16 x i8], [16 x i8]* %4, i64 0, i64 %82
%84 = load i8, i8* %83
store volatile i8 %84, i8* inttoptr (i64 3758145536 to i8*)
%85 = icmp eq i64 %82, 15
br i1 %85, label %86, label %59
86: ; preds = %55, %59, %40
ret void
}