3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 var_t
*var_find (char *name
)
36 for (var
= var_list
.next
; var
!= &var_list
; var
= var
->next
) {
37 if (!strcmp (var
->name
, name
))
44 int var_create (char type
, char *name
, unsigned len
, void *address
, unsigned line
)
48 /* alloc and init context */
49 var
= (var_t
*) malloc (sizeof (var_t
));
56 var
->name
= (char *) malloc (sizeof (char) * (len
+ 1));
61 memcpy (var
->name
, name
, len
);
62 var
->name
[len
] = '\0';
64 var
->address
= address
;
68 var
->next
= &var_list
;
69 var
->prev
= var_list
.prev
;
70 var
->prev
->next
= var
;
71 var
->next
->prev
= var
;
73 printf ("var_create () -> '%s' on line %d\n", var
->name
, line
);
78 int source_nextline (char *source
, unsigned size
)
82 for (i
= 0; i
< size
; i
++) {
83 //printf ("znak: %c : %d\n", source[i], source[i]);
84 if (source
[i
] == '\n') {
85 //printf ("source_nextline: %d\n", i);
93 char *source_param (char *source
, unsigned *size
)
96 char *param
= (char *) 0;
99 for (i
= 0; i
< len
; i
++) {
101 if (source
[i
] == ' ' || source
[i
] == '\t') {
106 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
107 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
108 (source
[i
] >= '0' && source
[i
] <= '9'))
110 } else if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == '\n' || source
[i
] == ';') {
119 char *source_paramfirst (char *source
, unsigned *size
)
122 char *param
= (char *) 0;
123 unsigned len
= *size
;
125 for (i
= 0; i
< len
; i
++) {
127 if (source
[i
] == ' ' || source
[i
] == '\t')
130 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
131 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
132 (source
[i
] >= '0' && source
[i
] <= '9'))
134 } else if (source
[i
] == ' ' || source
[i
] == ',' || source
[i
] == '\t') {
143 char *source_paramsecond (char *source
, unsigned *size
)
146 char *param
= (char *) 0;
147 unsigned len
= *size
;
149 for (i
= 0; i
< len
; i
++) {
151 if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == ',')
154 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
155 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
156 (source
[i
] >= '0' && source
[i
] <= '9'))
158 else if (source
[i
] == '\'')
160 } else if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == '\n' || source
[i
] == ';') {
169 int source_parse (char *source
, unsigned size
)
174 for (i
= 0; i
< size
; i
++) {
176 if (!strncmp ("global ", source
+i
, 7)) {
177 unsigned var
= size
-i
-7;
178 char *param
= source_param (source
+i
+7, &var
);
181 printf ("ERROR -> !param\n");
185 var_create (VAR_TYPE_GLOBAL
, param
, var
, (void *) 0x0 + i
, line
);
187 i
+= source_nextline (source
+i
, size
-i
);
194 if (!strncmp ("mov ", source
+i
, 4)) {
195 unsigned reg_len
= size
-i
-4;
196 char *paramreg
= source_paramfirst (source
+i
+4, ®_len
);
199 printf ("ERROR -> !paramreg\n");
203 unsigned val_len
= size
-reg_len
-i
-4;
204 char *paramval
= source_paramsecond (source
+i
+reg_len
+4, &val_len
);
207 printf ("ERROR -> !val_len\n");
211 i
+= source_nextline (source
+i
, size
-i
);
213 paramreg
[reg_len
] = '\0';
214 paramval
[val_len
] = '\0';
216 printf ("mov: %s, %s\n", paramreg
, paramval
);
218 unsigned char reg
= 0;
220 if (paramval
[0] != 'e') { /* MOV 8bit */
221 if (paramreg
[0] == 'e' && paramreg
[1] == 'a' && paramreg
[2] == 'x')
223 else if (paramreg
[0] == 'e' && paramreg
[1] == 'b' && paramreg
[2] == 'x')
225 else if (paramreg
[0] == 'e' && paramreg
[1] == 'c' && paramreg
[2] == 'x')
227 else if (paramreg
[0] == 'e' && paramreg
[1] == 'd' && paramreg
[2] == 'x')
230 buffer_copy (bin_pos
, (void *) ®
, 1);
233 /* Let's convert parameter to binary number */
234 if (paramval
[0] == '\'') {
236 printf ("ERROR -> wrong parameter syntax - %d != 3, line: %d\n", val_len
, line
);
240 if (paramval
[2] != '\'' || paramval
[1] == '\'') {
241 printf ("ERROR -> wrong parameter syntax, line: %d\n", line
);
246 //printf ("mov val char = %c\n", c);
248 buffer_copy (bin_pos
, (void *) &c
, sizeof (int));
249 bin_pos
+= sizeof (int);
251 } else if (paramval
[0] == '0' && paramval
[1] == 'x') {
252 char *endptr
, *str
= paramval
+2;
254 long val
= strtol (str
, &endptr
, 16);
256 //printf ("mov val hexa = %d\n", val);
258 buffer_copy (bin_pos
, (void *) &val
, sizeof (int));
259 bin_pos
+= sizeof (int);
262 for (x
= 0; x
< val_len
-1; x
++) {
263 if (!(paramval
[x
] >= '0' && paramval
[x
] <= '9')) {
264 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
269 int num
= atoi (paramval
);
271 //printf ("mov val digit = %d\n", num);
273 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
274 bin_pos
+= sizeof (int);
278 } else { /*MOV 32bit */
282 buffer_copy (bin_pos
, (void *) ®
, 1);
285 unsigned char regb
= 0;
287 if (!strncmp (paramreg
, "eax", 3)) {
288 if (!strncmp (paramval
, "eax", 3))
290 else if (!strncmp (paramval
, "ebx", 3))
292 else if (!strncmp (paramval
, "ecx", 3))
294 else if (!strncmp (paramval
, "edx", 3))
296 } else if (!strncmp (paramreg
, "ebx", 3)) {
297 if (!strncmp (paramval
, "eax", 3))
299 else if (!strncmp (paramval
, "ebx", 3))
301 else if (!strncmp (paramval
, "ecx", 3))
303 else if (!strncmp (paramval
, "edx", 3))
305 } else if (!strncmp (paramreg
, "ecx", 3)) {
306 if (!strncmp (paramval
, "eax", 3))
308 else if (!strncmp (paramval
, "ebx", 3))
310 else if (!strncmp (paramval
, "ecx", 3))
312 else if (!strncmp (paramval
, "edx", 3))
314 } else if (!strncmp (paramreg
, "edx", 3)) {
315 if (!strncmp (paramval
, "eax", 3))
317 else if (!strncmp (paramval
, "ebx", 3))
319 else if (!strncmp (paramval
, "ecx", 3))
321 else if (!strncmp (paramval
, "edx", 3))
325 buffer_copy (bin_pos
, (void *) ®b
, 1);
335 if (!strncmp ("int ", source
+i
, 4)) {
336 unsigned var
= size
-i
-4;
337 char *param
= source_param (source
+i
+4, &var
);
340 printf ("ERROR -> !param\n");
344 i
+= source_nextline (source
+i
, size
-i
);
346 unsigned char intr
= 0xcd; // int
347 buffer_copy (bin_pos
, (void *) &intr
, 1);
352 if (param
[0] == '0' && param
[1] == 'x') {
353 char *endptr
, *str
= param
+2;
355 long val
= strtol (str
, &endptr
, 16);
357 //printf ("int: 0x%x\n", val);
359 buffer_copy (bin_pos
, (void *) &val
, 1);
363 for (x
= 0; x
< var
; x
++) {
364 if (!isdigit (param
[x
])) {
365 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
370 int num
= atoi (param
);
372 buffer_copy (bin_pos
, (void *) &num
, 1);
376 printf ("int: %s\n", param
);
383 if (!strncmp ("jmp ", source
+i
, 4)) {
384 unsigned v
= size
-i
-4;
385 char *param
= source_param (source
+i
+4, &v
);
388 printf ("ERROR -> !param\n");
392 i
+= source_nextline (source
+i
, size
-i
);
394 unsigned char jmp
= 0xeb; // jmp
395 buffer_copy (bin_pos
, (void *) &jmp
, 1);
400 var_t
*var
= var_find (param
);
403 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
407 unsigned diff
= (bin_pos
- var
->offset
);
410 printf ("ERROR -> it is not 'near jump', line %d\n", line
);
414 unsigned char val
= 0xff - diff
;
416 buffer_copy (bin_pos
, (void *) &val
, 1);
419 printf ("jmp: %s\n", param
);
426 if (!strncmp ("inc ", source
+i
, 4)) {
427 unsigned v
= size
-i
-4;
428 char *param
= source_param (source
+i
+4, &v
);
431 printf ("ERROR -> !param\n");
435 i
+= source_nextline (source
+i
, size
-i
);
440 printf ("ERROR -> inc: bad register name '%s', line %d\n", param
, line
);
444 unsigned char reg
= 0;
446 if (!strncmp (param
, "eax", 3))
448 else if (!strncmp (param
, "ebx", 3))
450 else if (!strncmp (param
, "ecx", 3))
452 else if (!strncmp (param
, "edx", 3))
455 buffer_copy (bin_pos
, (void *) ®
, 1);
458 printf ("inc: %s\n", param
);
465 if (!strncmp ("ret", source
+i
, 3)) {
466 if (!function_curr
) {
467 printf ("ERROR -> ret cannot be called out of function, line: %d\n", line
);
471 printf ("Function %s end on line %d\n", function_curr
->name
, line
);
475 unsigned char ret
= 0xc3;
476 buffer_copy (bin_pos
, (void *) &ret
, 1);
479 i
+= source_nextline (source
+i
, size
-i
);
486 if (!strncmp ("hlt", source
+i
, 3)) {
487 unsigned char hlt
= 0xf4;
488 buffer_copy (bin_pos
, (void *) &hlt
, 1);
491 i
+= source_nextline (source
+i
, size
-i
);
497 if ((source
[i
] >= 'a' && source
[i
] <= 'z') || (source
[i
] >= 'A' && source
[i
] <= 'Z')) {
500 for (y
= i
; y
< size
-i
; y
++) {
502 if (source
[y
] == ':') {
505 var_t
*var
= var_find (source
+i
);
508 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
512 printf ("Function '%s' on line %d\n", var
->name
, line
);
514 var
->offset
= bin_pos
;
516 function_curr
= var
; // set current function
521 if (source
[y
] == ' ' || source
[y
] == '\t' || source
[y
] == '\n' || source
[y
] == 32 || source
[y
] == ';') {
524 printf ("ERROR -> unknown command '%s', line: %d - %d, %c\n", source
+i
, line
, i
, source
[i
]);
531 //if (source[i] != ' ' || source[i] != ';')
532 //printf ("ERROR -> unspecified character '%c', line: %d\n", source[i], line);
533 if (source
[i
] == ';') {
534 i
+= source_nextline (source
+i
, size
-i
);
540 if (source
[i
] == '\n')
547 char *source_open (char *file
, unsigned *size
)
549 int fd
= open (file
, O_RDONLY
);
552 printf ("error -> file '%s' not found !\n", file
);
556 char *buffer
= (char *) malloc (sizeof (char) * 10240);
559 printf ("ERROR -> out of memory !\n");
567 ret
= read (fd
, buffer
+l
, 512);
579 //printf ("Source: %s\n-=-=-=-=-=-=-=-=-\n\n", buffer);
586 var_list
.next
= &var_list
;
587 var_list
.prev
= &var_list
;