21d191018af8a204f27f6b950975d8c43f563373
[sped.git] / sped.asm
1 ; sped - the stupidly pointless editor
2 ; written by pinosaur
3
4 global main
5 extern printf
6 extern malloc
7 extern realloc
8 extern free
9 extern memset
10
11 ; macros
12 %macro write_str 2
13     mov eax, 4
14     mov ebx, 1
15     mov ecx, %1
16     mov edx, %2
17     int 0x80
18 %endmacro
19
20 section .data
21     banner_str db `SPED - the stupidly pointless editor\n`, 0x00
22     readfile_str db `reading file %s\n`, 0x00
23     nofile_str db `no file provided\n`, 0x00
24     argcount_str db `there are %d args\n`, 0x00
25     wrongfile_str db `unable to open file, error code: %i\n`, 0x00
26     char_str db `read this char: %i\n`, 0x00
27     printfint_str db `int: %i\n`, 0x00
28
29 section .text
30 main:
31     %define _ARGC 8
32     %define _ARGV 12
33
34     push ebp
35     mov ebp, esp
36
37     ; read command line args
38     mov ecx, [ebp+_ARGC]
39     cmp ecx, 1
40     jg _main_existing
41     
42     ; display error msg if no file
43     push nofile_str
44     call printf
45     mov eax, 1
46     jmp _main_exit
47
48     _main_existing:
49     mov ebx, DWORD [ebp+_ARGV]
50     add ebx, 4
51     push DWORD [ebx]
52     ; push readfile_str
53     ; call printf
54
55     call readFile
56
57     mov eax, 0
58     jmp _main_exit
59
60     _main_exit:
61     %undef _ARGC
62     %undef _ARGV
63
64     mov esp, ebp
65     pop ebp
66     ret
67
68
69 ; reads file line by line
70 ; args: filename
71 ; return:
72 ;    eax - pointer to mem
73 ;    ecx - lines read
74 readFile:
75     %define _FILE_NAME  8
76     %define FILE_HANDLE 4
77     %define IS_EOF      8
78     %define LINES_READ  12
79     %define BUF_PTR     16 ; malloced array of strings
80
81     push ebp
82     mov ebp, esp
83     
84     ; allocate vars
85     sub esp, 16
86     mov DWORD [ebp-FILE_HANDLE], 0x00
87     mov DWORD [ebp-IS_EOF], 0x00
88     mov DWORD [ebp-LINES_READ], 0x00
89
90     push 0
91     call malloc 
92     mov [ebp-BUF_PTR], eax
93
94     ; open existing file
95     mov eax, 5
96     mov ebx, [ebp+_FILE_NAME]
97     mov ecx, 0
98     mov edx, 0777
99     int 0x80
100     mov [ebp-FILE_HANDLE], eax
101
102     ; check if file was open successfully
103     cmp eax, 0
104     jge _readFile_loop
105     push eax
106     push wrongfile_str
107     call printf
108     jmp _readFile_exit
109
110     _readFile_loop:
111
112     ; check if eof was reached
113     cmp DWORD [ebp-IS_EOF], 1
114     je _readFile_exit
115
116     push DWORD [ebp-FILE_HANDLE]
117     call readLine 
118
119     mov esi, eax
120     mov [ebp-IS_EOF], ebx
121     
122     push esi
123     call printf
124
125     ; make string buffer bigger
126     mov eax, DWORD [ebp-LINES_READ]
127     add eax, 1
128     mov ecx, 4
129     mul ecx
130     push eax
131     push DWORD [ebp-BUF_PTR]
132     call realloc
133     mov DWORD [ebp-BUF_PTR], eax
134
135     ; write string to buffer
136     mov eax, DWORD [ebp-BUF_PTR]
137     mov ecx, 4
138     mul ecx
139     mov eax, esi
140
141     add DWORD [ebp-LINES_READ], 1
142
143     jmp _readFile_loop
144
145     _readFile_exit:
146     ; close file
147     mov eax, 6
148     mov ebx, [ebp-FILE_HANDLE]
149     int 0x80
150
151     %undef _FILE_NAME
152     %undef FILE_HANDLE
153     %undef IS_EOF
154     %undef LINES_READ
155     %undef BUF_PTR
156
157     mov esp, ebp
158     pop ebp
159     ret
160
161
162 ; reads a line until newline character is reached
163 ; args: file_handle
164 ; return:
165 ;   eax: location to buffer
166 ;   ebx: contains eof
167 readLine:
168     %define _FILE_HANDLE 8
169     %define CHAR_COUNT   4   ; count number of characters read
170     %define BLOCK_COUNT  8   ; number of 64 blocks we've read
171     %define STR_PTR      12  ; malloced buffer to store read string
172
173     push ebp
174     mov ebp, esp
175     
176     ; allocate vars
177     sub esp, 12
178     mov DWORD [ebp-CHAR_COUNT], 0x00
179     mov DWORD [ebp-BLOCK_COUNT], 0x00
180
181     push 64
182     call malloc
183     mov [ebp-STR_PTR], eax
184
185     push DWORD [ebp-STR_PTR]
186     push 0x00
187     push 64
188
189     _readLine_loop:
190     ; if buffer is full
191     cmp BYTE [ebp-CHAR_COUNT], 63 ; leave one byte for null byte
192     jne _readLine_notfull
193     jmp _readLine_exit
194
195     _readLine_notfull:
196     ; read a single character
197     mov eax, 3
198     mov ebx, [ebp+_FILE_HANDLE]
199     mov ecx, [ebp-STR_PTR]
200     add ecx, [ebp-CHAR_COUNT]
201     mov edx, 1
202     int 0x80
203
204     ; mov eax, 4
205     ; mov ebx, 1
206     ; mov ecx, [ebp-STR_PTR]
207     ; add ecx, [ebp-CHAR_COUNT]
208     ; mov edx, 1
209     ; int 0x80
210     
211     ; check for eof
212     cmp eax, 0 ; eax has zero on eof
213     jne _readLine_not_eof
214     mov ebx, 1
215     jmp _readLine_exit 
216     _readLine_not_eof:
217
218     ; check for newline
219     mov eax, [ebp-STR_PTR]
220     add eax, [ebp-CHAR_COUNT]
221     cmp DWORD [eax], 0x0a
222     jne _readLine_not_newline
223     mov ebx, 0
224     jmp _readLine_exit
225     _readLine_not_newline:
226
227     add DWORD [ebp-CHAR_COUNT], 1
228     jmp _readLine_loop
229
230     _readLine_exit:
231
232     mov eax, DWORD [ebp-STR_PTR]
233
234     %undef _FILE_HANDLE
235     %undef CHAR_COUNT
236     %undef BLOCK_COUNT 
237     %undef STR_PTR
238
239     mov esp, ebp
240     pop ebp
241     ret
242