// File: yanlinlin82[P]icpp/icpp.cpp
// Function: add_external_symbol(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int)
void add_external_symbol(string name, string args_type, string ret_type = "", int arg_count = 0)
{
	// for variable arguments, arg_count is negative, and the number is fixed arguments.
	// for example
	//   `int printf(const char* fmt, ...)`, arg_count is -1
	//   `int fprintf(FILE*, const char* fmt, ...)`, arg_count is -2
	// in runtime, an integer is appended after variable arguments, specifying their numbers.
	//   the number, as in stdcall calling convention (which means the arguments are pushed into
	//   stack as the order in source code, and this interpreter follows this rule), could be
	//   found as [bp + 1] in subroutine (before ENTER)
	if (ret_type.empty()) { // data
		size_t offset = data_sec.size();
		add_symbol(name, false, offset, 1, args_type, "", 0);
		data_sec.resize(offset + 1);
	} else { // code
		size_t offset = code_sec.size();
		string name_with_args = name + "(" + args_type + ")";
		override_functions[name].insert(name_with_args);
		add_symbol(name_with_args, true, offset, 2, args_type, ret_type, arg_count);
		add_assembly_code(RET, (arg_count >= 0 ? arg_count : 0), ret_type + " " + name_with_args);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdx, -0x1d8(%rbp)
movq %rdi, %rax
movq -0x1d8(%rbp), %rdi
movq %rax, -0x1d0(%rbp)
movq %rsi, -0x1c8(%rbp)
movq %rdi, -0x1c0(%rbp)
movq %rax, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdi, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
callq 0x3430
testb $0x1, %al
jne 0x5a8e
jmp 0x5bc1
leaq 0x4aadb(%rip), %rdi     # 0x50570
callq 0x19990
movq -0x1d0(%rbp), %rsi
movq %rax, -0x28(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x3120
movq -0x1c8(%rbp), %rsi
movq -0x28(%rbp), %rax
movq %rax, -0x1e0(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x3120
jmp 0x5acb
leaq -0x99(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x3470
movq -0x1e8(%rbp), %rdx
leaq 0x328d8(%rip), %rsi     # 0x383c4
leaq -0x98(%rbp), %rdi
callq 0x199b0
jmp 0x5afa
movq -0x1e0(%rbp), %rdx
movq %rsp, %rax
movl $0x0, (%rax)
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %ecx
leaq -0x68(%rbp), %r8
leaq -0x98(%rbp), %r9
callq 0x4840
jmp 0x5b27
leaq -0x98(%rbp), %rdi
callq 0x34d8
leaq -0x99(%rbp), %rdi
callq 0x32b0
leaq -0x68(%rbp), %rdi
callq 0x34d8
leaq -0x48(%rbp), %rdi
callq 0x34d8
movq -0x28(%rbp), %rsi
addq $0x1, %rsi
leaq 0x4aa10(%rip), %rdi     # 0x50570
callq 0x19bf0
jmp 0x5eba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5bb3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5b9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x34d8
leaq -0x99(%rbp), %rdi
callq 0x32b0
leaq -0x68(%rbp), %rdi
callq 0x34d8
leaq -0x48(%rbp), %rdi
callq 0x34d8
jmp 0x5ec3
leaq 0x4a990(%rip), %rdi     # 0x50558
callq 0x19990
movq -0x1d0(%rbp), %rsi
movq %rax, -0xa8(%rbp)
leaq 0x31d25(%rip), %rdx     # 0x37907
leaq -0x108(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
callq 0x1a540
movq -0x1f0(%rbp), %rsi
movq -0x1c8(%rbp), %rdx
leaq -0xe8(%rbp), %rdi
callq 0x1a4f0
jmp 0x5c11
leaq 0x31eb0(%rip), %rdx     # 0x37ac8
leaq -0xc8(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x1a4a0
jmp 0x5c2d
leaq -0xe8(%rbp), %rdi
callq 0x34d8
leaq -0x108(%rbp), %rdi
callq 0x34d8
movq -0x1d0(%rbp), %rsi
leaq 0x4aa3d(%rip), %rdi     # 0x50690
callq 0x1a020
movq %rax, -0x1f8(%rbp)
jmp 0x5c61
movq -0x1f8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x1a5c0
movb %dl, -0x201(%rbp)
movq %rax, -0x200(%rbp)
jmp 0x5c83
movb -0x201(%rbp), %al
movq -0x200(%rbp), %rcx
movq %rcx, -0x118(%rbp)
movb %al, -0x110(%rbp)
leaq -0x138(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x3120
jmp 0x5cb2
movq -0x1c8(%rbp), %rsi
movq -0xa8(%rbp), %rax
movq %rax, -0x210(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x3120
jmp 0x5cd5
movq -0x1c0(%rbp), %rsi
leaq -0x178(%rbp), %rdi
callq 0x3120
jmp 0x5cea
movq -0x210(%rbp), %rdx
movl -0x1c(%rbp), %ecx
movq %rsp, %rax
movl %ecx, (%rax)
leaq -0x138(%rbp), %rdi
movl $0x1, %esi
movl $0x2, %ecx
leaq -0x158(%rbp), %r8
leaq -0x178(%rbp), %r9
callq 0x4840
jmp 0x5d1f
leaq -0x178(%rbp), %rdi
callq 0x34d8
leaq -0x158(%rbp), %rdi
callq 0x34d8
leaq -0x138(%rbp), %rdi
callq 0x34d8
cmpl $0x0, -0x1c(%rbp)
jl 0x5d54
movl -0x1c(%rbp), %eax
movl %eax, -0x214(%rbp)
jmp 0x5d5e
xorl %eax, %eax
movl %eax, -0x214(%rbp)
jmp 0x5d5e
movq -0x1c0(%rbp), %rsi
movl -0x214(%rbp), %eax
movl %eax, -0x218(%rbp)
leaq 0x31448(%rip), %rdx     # 0x371c0
leaq -0x1b8(%rbp), %rdi
callq 0x1a540
jmp 0x5d86
leaq -0x198(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
leaq -0xc8(%rbp), %rdx
callq 0x1a4f0
jmp 0x5da2
movl -0x218(%rbp), %esi
movl $0x26, %edi
leaq -0x198(%rbp), %rdx
callq 0x56e0
jmp 0x5dbb
leaq -0x198(%rbp), %rdi
callq 0x34d8
leaq -0x1b8(%rbp), %rdi
callq 0x34d8
leaq -0xc8(%rbp), %rdi
callq 0x34d8
jmp 0x5eba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5e0a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x34d8
leaq -0x108(%rbp), %rdi
callq 0x34d8
jmp 0x5ec3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5eac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5e6c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5e60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x34d8
leaq -0x158(%rbp), %rdi
callq 0x34d8
leaq -0x138(%rbp), %rdi
callq 0x34d8
jmp 0x5eac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5ea0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x34d8
leaq -0x1b8(%rbp), %rdi
callq 0x34d8
leaq -0xc8(%rbp), %rdi
callq 0x34d8
jmp 0x5ec3
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
movq -0x70(%rbp), %rdi
callq 0x3460
nopl (%rax)