-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasm_palindrome.asm
163 lines (150 loc) · 3.39 KB
/
asm_palindrome.asm
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
%define BOTH_UPPER 0x0A
%define FIRST_UP_SECOND_LOW 0x06
%define FIRST_LOW_SECOND_UP 0x09
%define BOTH_LOWER 0x05
%define L_ALNUM 0x03
%define H_ALNUM 0x0C
section .text
global ispalindrome
ispalindrome:
; rdi: s
; rsi: linelen -> h
; rcx: l
; rdx: scase
; r8: sl
; r9: sh
xor ecx, ecx ; char l = 0;
sub rsi, 1 ; int h = linelen - 1;
xor edx, edx ; char scase = 0x00;
.top_loop: ; while (l < h)
cmp ecx, esi
jge .end
movzx r8, byte [rdi + rcx] ; sl = s[l];
movzx r9, byte [rdi + rsi] ; sh = s[h];
.sl_lower:
; if ('a' <= sl && sl <= 'z')
cmp r8, 'a'
jl .sl_upper
cmp r8, 'z'
jg .sl_upper
; scase |= (1 << 0);
or edx, 1
.sl_upper:
; if ('A' <= sl && sl <= 'Z')
cmp r8, 'A'
jl .sh_lower
cmp r8, 'Z'
jg .sh_lower
; scase |= (1 << 1);
or edx, 2
.sh_lower:
; if ('a' <= sh && sh <= 'z')
cmp r9, 'a'
jl .sh_upper
cmp r9, 'z'
jg .sh_upper
; scase |= (1 << 2);
or edx, 4
.sh_upper:
; if ('A' <= sh && sh <= 'Z')
cmp r9, 'A'
jl .l_loop
cmp r9, 'Z'
jg .l_loop
; scase |= (1 << 3);
or edx, 8
.l_loop:
; while (!(scase & L_ALNUM))
mov eax, edx
and rax, L_ALNUM
cmp eax, 0
jne .h_loop
; sl = s[++l]
add ecx, 1
movzx r8, byte [rdi + rcx]
.l_loop_sl_lower:
;if ('a' <= sl && sl <= 'z') scase |= (1 << 0)
cmp r8, 'a'
jl .l_loop_sl_upper
cmp r8, 'z'
jg .l_loop_sl_upper
or edx, 1
.l_loop_sl_upper:
; if ('A' <= sl && sl <= 'Z') scase |= (1 << 1)
cmp r8, 'A'
jl .l_loop
cmp r8, 'Z'
jg .l_loop
or edx, 2
jmp .l_loop
.h_loop:
; while (!(scase & H_ALNUM))
mov eax, edx
and rax, H_ALNUM
cmp eax, 0
jne .both_upper
; sh = s[--h];
sub rsi, 1
movzx r9, byte [rdi + rsi]
.h_loop_sh_lower:
; if ('a' <= sh && sh <= 'z') scase |= (1 << 2);
cmp r9, 'a'
jl .h_loop_sh_upper
cmp r9, 'z'
jg .h_loop_sh_upper
or edx, 4
.h_loop_sh_upper:
; if ('A' <= sh && sh <= 'Z') scase |= (1 << 3);
cmp r9, 'A'
jl .h_loop
cmp r9, 'Z'
jg .h_loop
or edx, 8;
jmp .h_loop
.both_upper:
; ((scase == BOTH_UPPER) && (sl != sh))
mov eax, edx
cmp rax, BOTH_UPPER
jne .first_up_second_low
cmp r8, r9
je .end_top_loop
jne .end_not_palindrome
.first_up_second_low:
; ((scase == FIRST_UP_SECOND_LOW) && (sl != sh-32))
mov eax, edx
cmp rax, FIRST_UP_SECOND_LOW
jne .first_low_second_up
mov r11, r9
sub r11, 32
cmp r8, r11
je .end_top_loop
jne .end_not_palindrome
.first_low_second_up:
; ((scase == FIRST_LOW_SECOND_UP) && (sl-32 != sh))
mov eax, edx
cmp rax, FIRST_LOW_SECOND_UP
jne .both_lower
mov r11, r8
sub r11, 32
cmp r11, r9
je .end_top_loop
jne .end_not_palindrome
.both_lower:
; ((scase == BOTH_LOWER) && (sl != sh))
mov eax, edx
cmp rax, BOTH_LOWER
jne .end_top_loop
cmp r8, r9
je .end_top_loop
jne .end_not_palindrome
.end_top_loop:
sub rsi, 1 ; h--;
add rcx, 1 ; l++;
xor rdx, rdx ; scase = 0x00;
jmp .top_loop
.end_not_palindrome:
xor eax, eax
ret
.end:
mov eax, 1
ret