-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpstring.s
More file actions
234 lines (180 loc) · 7.03 KB
/
pstring.s
File metadata and controls
234 lines (180 loc) · 7.03 KB
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# Autor - Yossi Maatook
.data
d: .string "%d"
s: .string "%s"
format_error_input: .string "invalid input!\n"
.text
.global pstrlen
.type pstrlen, @function
# rdi = pstring pointer
pstrlen:
push %rbp
mov %rsp, %rbp
movzbq (%rdi),%rax # rax = recived pstring length
mov %rbp,%rsp
pop %rbp
ret
.global swapCase
.type swapCase, @function
# rdi = pstring pointer
swapCase:
push %rbp
mov %rsp, %rbp
movzbq (%rdi), %rbx # rbx = pstring length
mov %rdi, %rax # rax = pstring address
.swapCase_while_l1:
cmp $0, %rbx # compare length to 0
jg .swapCase_while_l2 # if length > 0, iterate on string and switch case every char
mov %rbp,%rsp # else, return
pop %rbp
ret
.swapCase_while_l2:
leaq 1(%rdi), %rdi # point to next char on string
movzbq (%rdi),%r10 # get current char
cmpb $64, %r10b
ja .bigger_64 # if current char ascii value is bigger 64, keep checking
# else, its not a letter in the ABC and continue to next char:
dec %rbx # pstring length--
jmp .swapCase_while_l1
.bigger_64:
cmpb $90, %r10b
ja .bigger_90 # if current char's ascii value is bigger than 91
add $32, (%rdi) # else: 64 < ascii value < 91 so add 32 and upper case it.
jmp .advance # go to next char
.bigger_90:
cmpb $96, %r10b
ja .bigger_96 # if current char's ascii value is bigger than 96
jmp .advance # else, advance to next char
.bigger_96:
cmpb $123, %r10b
jb .low_case # if current char's: 96 < ascii value < 123, lower case it.
jmp .advance # else, advance to next char
.low_case:
subb $32, (%rdi) # subtract 32 from upper case letter to make it lower case
.advance:
dec %rbx # pstring length--
jmp .swapCase_while_l1 # go to next char
.global replaceChar
.type replaceChar, @function
# rdi = pstring pointer, rsi = old char, rdx = new char
replaceChar:
push %rbp
mov %rsp, %rbp
mov %rdi, %rax
movzbq (%rdi), %rcx # rcx = pstring length
.replaceChar_condition:
cmp $0,%rcx
jg .replaceChar_while # in case havent reached end of string
mov %rbp,%rsp # else, return
pop %rbp
ret
.replaceChar_while:
inc %rdi # go to next char
movzbq (%rdi), %r10 # r10 = current char
dec %rcx # pstring length--
cmp %r10b, %sil # compare current char to "old char"
jne .replaceChar_condition # if diffrent, go to next char
mov %dl, (%rdi) # else, replace current with old char
jmp .replaceChar_condition # go to next char
.global pstrijcpy
.type pstrijcpy, @function
# rdi = p1, rsi = p2, rdx = i, rcx = j
pstrijcpy:
push %rbp
mov %rsp, %rbp
call is_valid # check if args are valid
cmp $1,%rax
je .cpy # if valid, go to cpy and execute the fucntion
mov $-2,%rax # else, return -2
mov %rbp,%rsp
pop %rbp
ret
.cpy:
leaq (%rdi,%rdx),%rdi # rdi points to p1[i]
leaq (%rsi,%rdx),%rsi # rsi points to p2[i]
sub %rdx, %rcx # rcx = j - i
.pstrijcmp.while:
inc %rdi # advacne to next char
inc %rsi
movzbq (%rsi), %r10 # r10 = p1[i] char
movb %r10b, (%rdi) # p2[i] = p1[i]
dec %rcx # rcx--
cmp $0, %rcx # compare 0 to remainning length
jge .pstrijcmp.while # in case havent reached the string endding, go to next char
mov %rbp,%rsp
pop %rbp
ret
.global pstrijcmp
.type pstrijcmp, @function
# rdi = p1, rsi = p2, rdx = i, rcx = j
pstrijcmp:
push %rbp
mov %rsp, %rbp
call is_valid # check if args are valid
cmp $1,%rax
je .cmp # if valid, go to cpy and execute the fucntion
mov $-2,%rax # else, return -2
mov %rbp,%rsp
pop %rbp
ret
.cmp:
leaq 1(%rdi,%rdx),%rdi # rdi points to p1[i]
leaq 1(%rsi,%rdx),%rsi # rsi points to p2[i]
sub %rdx, %rcx # rcx = j - i
.pstrijcmp.compare:
movzbq (%rdi), %r10 # r10 = p1[i] char
movzbq (%rsi), %r11 # r11 = p2[i] char
cmpb %r11b, %r10b
je .pstrijcmp_condition # in case p1[i]=p2[i], go to next char
ja .return_p1_bigger # elif p1[i]>p2[i], p1 is bigger
mov $-1, %rax # else, p2 is bigger
mov %rbp,%rsp
pop %rbp
ret
.return_p1_bigger:
mov $1, %rax # return 1 - p1 is bigger
mov %rbp,%rsp
pop %rbp
ret
.pstrijcmp_condition:
inc %rsi # go to next char on p2
inc %rdi # go to next char on p1
dec %rcx # rcx--
cmp $0, %rcx # compare 0 to remainning length
jge .pstrijcmp.compare # in case havent reached the string endding, go to next char
mov $0, %rax # else, strings are equal
mov %rbp,%rsp
pop %rbp
ret
.global is_valid
.type is_valid, @function
# rdi = p1, rsi = p2, rdx = i, rcx = j
# checks if recived args are valid - if i and j are in the p1 and p2 bounds and i<j.
# returns 1 if valid and -2 otherwise.
is_valid:
push %rbp
mov %rsp, %rbp
movzbq (%rsi), %r10 # r10 = p1 length
cmpb %r10b,%dl
jge .invalid_input # in case i is out of p1 bound
cmpb %r10b,%cl
jge .invalid_input # in case j is out of p1 bound
movzbq (%rdi), %r10 # r10 = p1 length
cmpb %r10b,%dl
jge .invalid_input # in case i is out of p2 bound
cmpb %r10b,%cl
jge .invalid_input # in case j is out of p2 bound
cmp %rdx, %rcx
jl .invalid_input # in case i > j
mov $1, %rax # return args are valid
mov %rbp,%rsp
pop %rbp
ret
.invalid_input:
leaq format_error_input(%rip),%rdi
xor %rax,%rax
call printf
mov $-2,%rax # return invalid
mov %rbp,%rsp
pop %rbp
ret