// File: iZhangHui[P]CppPrimer/CH02_VariablesAndBasicTypes/examples/unsigned.cc
// Function: main
int main()
{
	unsigned u = 10, u2 = 42;
	std::cout << u2 - u << std::endl;  
	std::cout << u - u2 << std::endl; 

	int i = 10, i2 = 42;
	std::cout << i2 - i << std::endl;
	std::cout << i - i2 << std::endl;

	u = 42;
	i = 10;
	std::cout << i - u << std::endl;
	std::cout << u - i << std::endl;

	u = 10;
	i = -42;
	std::cout << i + i << std::endl;  // prints -84
	std::cout << u + i << std::endl;  // if 32-bit ints, prints 4294967264

	i = 10;
	std::cout << "good" << std::endl;
	while (i >= 0) {
		std::cout << i << std::endl;
		--i;
	}

	for (int i = 10; i >= 0; --i)
		std::cout << i << std::endl;

	for (unsigned u = 0; u <= 10; ++u) 
		std::cout << u << std::endl;  // prints 0 . . . 10

/* NOTE: the condition in the following loop 
         will run indefinitely
	// WRONG: u can never be less than 0; the condition will always succeed
	for (unsigned u = 10; u >= 0; --u)
    	std::cout << u << std::endl;
*/
	u = 11; // start the loop one past the first element we want to print
	while (u > 0) {
		 --u;        // decrement first, so that the last iteration will print 0
		std::cout << u << std::endl;  
	}

	// be wary of comparing ints and unsigned
	u = 10;
	i = -42;
	if (i < u)               // false: i is converted to unsigned
		std::cout << i << std::endl;
	else
		std::cout << u << std::endl;   // prints 10

	u = 42; u2 = 10;
	std::cout << u - u2 << std::endl; // ok: result is 32
	std::cout << u2 - u << std::endl; // ok: but the result will wrap around
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movl $0x0, -0x4(%rbp)
movl $0xa, -0x8(%rbp)
movl $0x2a, -0xc(%rbp)
movl -0xc(%rbp), %esi
subl -0x8(%rbp), %esi
movq 0x2dde(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2dbf(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x8(%rbp), %esi
subl -0xc(%rbp), %esi
movq 0x2dbd(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2d9e(%rip), %rsi      # 0x3fc8
callq 0x1050
movl $0xa, -0x10(%rbp)
movl $0x2a, -0x14(%rbp)
movl -0x14(%rbp), %esi
subl -0x10(%rbp), %esi
movq 0x2d8e(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
movq 0x2d6f(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x10(%rbp), %esi
subl -0x14(%rbp), %esi
movq 0x2d6d(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
movq 0x2d4e(%rip), %rsi      # 0x3fc8
callq 0x1050
movl $0x2a, -0x8(%rbp)
movl $0xa, -0x10(%rbp)
movl -0x10(%rbp), %esi
subl -0x8(%rbp), %esi
movq 0x2d3e(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2d1f(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x8(%rbp), %esi
subl -0x10(%rbp), %esi
movq 0x2d1d(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2cfe(%rip), %rsi      # 0x3fc8
callq 0x1050
movl $0xa, -0x8(%rbp)
movl $0xffffffd6, -0x10(%rbp) # imm = 0xFFFFFFD6
movl -0x10(%rbp), %esi
addl -0x10(%rbp), %esi
movq 0x2cee(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
movq 0x2ccf(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x8(%rbp), %esi
addl -0x10(%rbp), %esi
movq 0x2ccd(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2cae(%rip), %rsi      # 0x3fc8
callq 0x1050
movl $0xa, -0x10(%rbp)
movq 0x2cab(%rip), %rdi      # 0x3fd8
leaq 0xcd0(%rip), %rsi       # 0x2004
callq 0x1040
movq %rax, %rdi
movq 0x2c85(%rip), %rsi      # 0x3fc8
callq 0x1050
cmpl $0x0, -0x10(%rbp)
jl 0x1377
movl -0x10(%rbp), %esi
movq 0x2c80(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
movq 0x2c61(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x10(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x1348
movl $0xa, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jl 0x13ad
movl -0x18(%rbp), %esi
movq 0x2c4a(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
movq 0x2c2b(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x18(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x137e
movl $0x0, -0x1c(%rbp)
cmpl $0xa, -0x1c(%rbp)
ja 0x13e3
movl -0x1c(%rbp), %esi
movq 0x2c14(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2bf5(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x13b4
movl $0xb, -0x8(%rbp)
cmpl $0x0, -0x8(%rbp)
jbe 0x1419
movl -0x8(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8(%rbp)
movl -0x8(%rbp), %esi
movq 0x2bd5(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2bb6(%rip), %rsi      # 0x3fc8
callq 0x1050
jmp 0x13ea
movl $0xa, -0x8(%rbp)
movl $0xffffffd6, -0x10(%rbp) # imm = 0xFFFFFFD6
movl -0x10(%rbp), %eax
cmpl -0x8(%rbp), %eax
jae 0x144f
movl -0x10(%rbp), %esi
movq 0x2b9f(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
movq 0x2b80(%rip), %rsi      # 0x3fc8
callq 0x1050
jmp 0x146d
movl -0x8(%rbp), %esi
movq 0x2b7f(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2b60(%rip), %rsi      # 0x3fc8
callq 0x1050
movl $0x2a, -0x8(%rbp)
movl $0xa, -0xc(%rbp)
movl -0x8(%rbp), %esi
subl -0xc(%rbp), %esi
movq 0x2b50(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2b31(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0xc(%rbp), %esi
subl -0x8(%rbp), %esi
movq 0x2b2f(%rip), %rdi      # 0x3fd8
callq 0x1060
movq %rax, %rdi
movq 0x2b10(%rip), %rsi      # 0x3fc8
callq 0x1050
movl -0x4(%rbp), %eax
addq $0x20, %rsp
popq %rbp
retq