-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path059.asm
128 lines (111 loc) · 4.23 KB
/
059.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
section .data
msg db "%d", 10, 0 ;return string for printf
file db "0059_cipher.txt", 0 ;file name
section .bss
buf resb 5000 ;buffer for file contents
cip resb 5000 ;cipher
key resb 3 ;key
section .text
extern printf
global main
main:
mov eax, 5 ;file open
mov edi, file ;file name
mov esi, 0 ;read only
syscall
mov edi, eax ;file descriptor
mov eax, 3 ;read
mov esi, buf ;into buffer
mov edx, 5000 ;5000 bytes
syscall
mov edi, eax ;file descriptor
mov eax, 6 ;close
syscall
xor edi, edi ;array index for buf
xor esi, esi ;array index for cip
xor eax, eax ;for chars
xor ebx, ebx ;dito
xor ecx, ecx ;sum
getcipher:
mov al, [buf + edi] ;buf[edi] in al
cmp byte al, 0 ;end of content?
je decode ;if yes, start decoding
sub al, '0' ;convert digit char to int
inc edi ;next char
cmp byte [buf + edi], ',' ;is it a comma?
jne greater9 ;if not, number is >= 10
mov [cip + esi], al ;else put number in cip[esi]
inc edi ;increase indices
inc esi
jmp getcipher ;and repeat
greater9:
mov bl, [buf + edi] ;second digit in bl
sub bl, '0' ;convert to int
imul eax, 10 ;multiply eax by 10
add al, bl ;add second digit
mov [cip + esi], al ;result in cip[esi]
inc esi ;increase indices
add edi, 2
jmp getcipher ;and repeat
decode:
mov byte [cip + esi], 255 ;end of data flag
mov byte [cip + esi + 1], 255 ;end of data flag
mov byte [cip + esi + 2], 255 ;end of data flag
xor edi, edi ;key index
xor eax, eax ;reset registers
xor ebx, ebx
xor esi, esi
nextkeychar:
cmp edi, 3 ;finished?
je getsum ;if yes, get the sum
mov bl, 'a' ;'a' in bl
mov esi, edi ;reset cipher index
testkeychar:
cmp byte [cip + esi], 255 ;end of cipher reached?
je valid ;if yes, key char is valid
mov al, [cip + esi] ;else put cip[esi] in al
xor eax, ebx
mov [buf + esi], al
cmp eax, 32 ;result < 32 (Space)?
jl notvalid ;if yes, key char is not valid
cmp eax, 122 ;result > 122 ('z')?
jg notvalid ;dito
cmp eax, 92 ;result = '\' or '`'?
je notvalid ;dito
cmp eax, 96
je notvalid
add esi, 3 ;else increase index and repeat
jmp testkeychar
notvalid:
inc bl ;next char in key[edi]
mov esi, edi ;reset cipher index
jmp testkeychar ;test that char
valid:
mov [key + edi], bl ;put char in key[edi]
inc edi ;increase key index
jmp nextkeychar ;and test next char
getsum:
sub esi, 2 ;reset esi to end of text
mov byte [buf + esi], 255 ;end of data flag
xor edi, edi ;reset registers
xor eax, eax
sumloop:
mov al, [buf + edi] ;char in al
cmp byte al, 255 ;end of text?
je print ;if yes, print result
add ecx, eax ;else add ascii value to sum
inc edi ;increase index
jmp sumloop ;and repeat
print: ;printing routine, differs slightly from OS to OS
push rbp
mov edi, msg
mov esi, ecx
call printf
pop rbp
exit: ;exit routine, dito
mov eax, 1
xor edi, edi
syscall
back:
ret
section .note.GNU-stack ;just for gcc