1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const int kMaxN = 50 * 1000;

extern "C" {
	char indata[kMaxN];
	char a[kMaxN];
	char b[kMaxN];
	char c[kMaxN];

	char memo_res[128] =
	{0, '1', 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, '0', '1',
	 '2', '3', '4', '5', '6', '7', '8', '9', '0', '1',
	 '2', '3', '4', '5', '6', '7', '8', '9', 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, '0', '1', '2', '3',
         '4', '5', '6', '7', '8', '9', '0', '1', '2', '3',
         '4', '5', '6', '7', '8', '9'};

	char memo_carry[128] =
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
	 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
	 1, 1, 1, 1, 1, 1};

};

void run() {
	asm("jmp do_all%=  \n"

	"read_input%=:  \n"
	    "movq $0, %%rdi  \n"
	    "leaq indata, %%rsi  \n"
	    "movq $40000, %%rdx  \n"
	    "call read  \n"
	    "leaq -1(%%rax), %%rcx  \n"
	    "movl $10, %%eax  \n"
	    "leaq indata, %%rdi  \n"
	    "repne scasb  \n"
	    "pushq %%rdi  \n"
	    "movq %%rdi, %%rsi  \n"
	    "leaq b, %%rdi  \n"
	    "rep movsb  \n"
	    "popq %%rcx  \n"
	    "leaq indata, %%rsi  \n"
	    "subq %%rsi, %%rcx  \n"
	    "decq %%rcx  \n"
	    "leaq a, %%rdi  \n"
	    "rep movsb  \n"
	    "ret  \n"

	"rev_string%=: \n"
	    "movq %%rdi, %%rsi  \n"
	    "xorq %%rax, %%rax  \n"
	    "movq $50000, %%rcx  \n"
	    "repne scasb  \n"
	    "decq %%rdi  \n"
	"rev_string_loop1%=: \n"
	    "cmpq %%rdi, %%rsi  \n"
	    "jl rev_string_loop2%= \n"
	    "ret  \n"
	"rev_string_loop2%=: \n"
	    "decq %%rdi  \n"
	    "movb (%%rsi), %%al  \n"
	    "xchgb (%%rdi), %%al \n"
	    "movb %%al, (%%rsi)  \n"
	    "incq %%rsi  \n"
	    "jmp rev_string_loop1%=  \n"

	"main_add%=:  \n"
	    "leaq a, %%rdi  \n"
	    "leaq b, %%rsi  \n"
	    "leaq c, %%rdx  \n"
	    "movq $40000, %%rcx  \n"
	    "xorq %%rax, %%rax  \n"
	"main_add_loop1%=:  \n"
	    "addb (%%rdi), %%al  \n"
	    "addb (%%rsi), %%al  \n"
	    "movb memo_res(%%rax), %%bl  \n"
	    "movb %%bl, (%%rdx)  \n"
	    "movb memo_carry(%%rax), %%al  \n"
	    "incq %%rdi  \n"
	    "incq %%rsi  \n"
	    "incq %%rdx  \n"
	    "loop main_add_loop1%=  \n"
	    "ret  \n"

	"do_print%=:  \n"
	    "leaq c, %%rdi  \n"
	    "xorq %%rax, %%rax  \n"
	    "movq $50000, %%rcx  \n"
	    "repne scasb  \n"
	    "movq %%rdi, %%rdx  \n"
	    "movb $10, -1(%%rdx)  \n"
	    "leaq c, %%rsi  \n"
	    "subq %%rsi, %%rdx  \n"
	    "movq $1, %%rdi  \n"
	    "call write  \n"
	    "ret  \n"


	"do_all%=:  \n"
	    "call read_input%= \n"
	    "leaq a, %%rdi  \n"
	    "call rev_string%=  \n"
	    "leaq b, %%rdi  \n"
	    "call rev_string%=  \n"
	    "call main_add%=  \n"
	    "leaq c, %%rdi  \n"
	    "call rev_string%=  \n"
	    "call do_print%=  \n"
	   :
	   :
	   : "rdi", "rcx", "rsi", "rax", "rdx", "rbx"
	   );
}

int main() {
	run();
}