// File: aisthesis[P]realnumber/src/array_arithmetic.cpp
// Function: array_arithmetic::subtract(unsigned char const*, unsigned char const*, unsigned char*, unsigned long const&, unsigned long const&)
void subtract(const unsigned char* a, const unsigned char* b, unsigned char* result,
			const std::size_t& a_len, const std::size_t& b_len) {
		std::size_t i;
		// copy of a is needed because we have to modify it when we borrow
		unsigned char* a_copy = new unsigned char[a_len];
		for (i = 0; i < a_len; ++i) { a_copy[i] = a[i]; }
		std::size_t ab_len_diff = a_len - b_len;
		i = b_len;
		int borrow_index;
		while (i > 0) {
			--i;
			if (a_copy[i + ab_len_diff] >= b[i]) { result[i + ab_len_diff] = a_copy[i + ab_len_diff] - b[i]; }
			else {
				result[i + ab_len_diff] = RADIX + a_copy[i + ab_len_diff] - b[i];
				borrow_index = i + ab_len_diff - 1;
				// get to a point where there is something to borrow
				while (borrow_index > 0 && a_copy[borrow_index] == 0) {
					a_copy[borrow_index--] = RADIX_MINUS_ONE;
				}
				--a_copy[borrow_index];
			}
		}
		i = ab_len_diff;
		while (i > 0) {
			--i;
			result[i] = a_copy[i];
		}
		delete[] a_copy;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0x2030
movq %rax, -0x38(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x5aa5
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x5a74
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
subq (%rcx), %rax
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jbe 0x5bc7
movq -0x30(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
addq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movq -0x10(%rbp), %rcx
movq -0x30(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jl 0x5b2d
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
addq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movq -0x10(%rbp), %rcx
movq -0x30(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
subl %ecx, %eax
movb %al, %dl
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rcx
addq -0x40(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x5bc2
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
addq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
addl $0x100, %eax            # imm = 0x100
movq -0x10(%rbp), %rcx
movq -0x30(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
subl %ecx, %eax
movb %al, %dl
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rcx
addq -0x40(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x30(%rbp), %rax
addq -0x40(%rbp), %rax
subq $0x1, %rax
movl %eax, -0x44(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x44(%rbp)
movb %al, -0x45(%rbp)
jle 0x5b90
movq -0x38(%rbp), %rax
movslq -0x44(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
sete %al
movb %al, -0x45(%rbp)
movb -0x45(%rbp), %al
testb $0x1, %al
jne 0x5b99
jmp 0x5bb1
movq -0x38(%rbp), %rax
movl -0x44(%rbp), %ecx
movl %ecx, %edx
addl $-0x1, %edx
movl %edx, -0x44(%rbp)
movslq %ecx, %rcx
movb $-0x1, (%rax,%rcx)
jmp 0x5b70
movq -0x38(%rbp), %rax
movslq -0x44(%rbp), %rcx
movb (%rax,%rcx), %dl
addb $-0x1, %dl
movb %dl, (%rax,%rcx)
jmp 0x5ac2
movq -0x40(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jbe 0x5bfa
movq -0x30(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x5bcf
movq -0x38(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, %rax
je 0x5c11
movq -0x50(%rbp), %rdi
callq 0x2200
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)