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/>.
33 var_t
*var_find (char *name
)
37 for (var
= var_list
.next
; var
!= &var_list
; var
= var
->next
) {
38 if (!strcmp (var
->name
, name
))
45 var_t
*var_create (char type
, char *name
, unsigned len
, void *address
, unsigned line
)
49 /* alloc and init context */
50 var
= (var_t
*) malloc (sizeof (var_t
));
57 var
->name
= (char *) malloc (sizeof (char) * (len
+ 1));
62 memcpy (var
->name
, name
, len
);
63 var
->name
[len
] = '\0';
65 var
->address
= address
;
69 var
->next
= &var_list
;
70 var
->prev
= var_list
.prev
;
71 var
->prev
->next
= var
;
72 var
->next
->prev
= var
;
74 printf ("var_create () -> '%s' on line %d\n", var
->name
, line
);
79 int source_nextline (char *source
, unsigned size
)
83 for (i
= 0; i
< size
; i
++) {
84 //printf ("znak: %c : %d\n", source[i], source[i]);
85 if (source
[i
] == '\n') {
86 //printf ("source_nextline: %d\n", i);
94 char *source_param (char *source
, unsigned *size
)
97 char *param
= (char *) 0;
100 for (i
= 0; i
< len
; i
++) {
102 if (source
[i
] == ' ' || source
[i
] == '\t') {
107 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
108 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
109 (source
[i
] >= '0' && source
[i
] <= '9'))
111 } else if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == '\n' || source
[i
] == ';') {
120 char *source_paramfirst (char *source
, unsigned *size
)
123 char *param
= (char *) 0;
124 unsigned len
= *size
;
126 for (i
= 0; i
< len
; i
++) {
128 if (source
[i
] == ' ' || source
[i
] == '\t')
131 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
132 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
133 (source
[i
] >= '0' && source
[i
] <= '9'))
135 } else if (source
[i
] == ' ' || source
[i
] == ',' || source
[i
] == '\t') {
144 char *source_paramsecond (char *source
, unsigned *size
)
147 char *param
= (char *) 0;
148 unsigned len
= *size
;
150 for (i
= 0; i
< len
; i
++) {
152 if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == ',')
155 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
156 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
157 (source
[i
] >= '0' && source
[i
] <= '9'))
159 else if (source
[i
] == '\'')
161 } else if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == '\n' || source
[i
] == ';') {
170 int source_parse (char *source
, unsigned size
)
175 for (i
= 0; i
< size
; i
++) {
177 if (!strncmp ("global ", source
+i
, 7)) {
178 unsigned var
= size
-i
-7;
179 char *param
= source_param (source
+i
+7, &var
);
182 printf ("ERROR -> !param\n");
186 var_create (VAR_TYPE_GLOBAL
, param
, var
, (void *) 0x0 + i
, line
);
188 i
+= source_nextline (source
+i
, size
-i
);
195 if (!strncmp ("mov ", source
+i
, 4)) {
196 unsigned reg_len
= size
-i
-4;
197 char *paramreg
= source_paramfirst (source
+i
+4, ®_len
);
200 printf ("ERROR -> !paramreg\n");
204 unsigned val_len
= size
-reg_len
-i
-4;
205 char *paramval
= source_paramsecond (source
+i
+reg_len
+4, &val_len
);
208 printf ("ERROR -> !val_len\n");
212 i
+= source_nextline (source
+i
, size
-i
);
214 paramreg
[reg_len
] = '\0';
215 paramval
[val_len
] = '\0';
217 printf ("mov: %s, %s\n", paramreg
, paramval
);
219 unsigned char reg
= 0;
221 if (paramval
[0] != 'e') { /* MOV 8bit/32bit */
222 if (paramreg
[0] == 'e' && paramreg
[1] == 'a' && paramreg
[2] == 'x')
224 else if (paramreg
[0] == 'e' && paramreg
[1] == 'b' && paramreg
[2] == 'x')
226 else if (paramreg
[0] == 'e' && paramreg
[1] == 'c' && paramreg
[2] == 'x')
228 else if (paramreg
[0] == 'e' && paramreg
[1] == 'd' && paramreg
[2] == 'x')
231 buffer_copy (bin_pos
, (void *) ®
, 1);
234 /* Let's convert parameter to binary number */
235 if (paramval
[0] == '\'') {
237 printf ("ERROR -> wrong parameter syntax - %d != 3, line: %d\n", val_len
, line
);
241 if (paramval
[2] != '\'' || paramval
[1] == '\'') {
242 printf ("ERROR -> wrong parameter syntax, line: %d\n", line
);
247 //printf ("mov val char = %c\n", c);
249 buffer_copy (bin_pos
, (void *) &c
, sizeof (int));
250 bin_pos
+= sizeof (int);
252 } else if (paramval
[0] == '0' && paramval
[1] == 'x') {
253 char *endptr
, *str
= paramval
+2;
255 long val
= strtol (str
, &endptr
, 16);
257 //printf ("mov val hexa = %d\n", val);
259 buffer_copy (bin_pos
, (void *) &val
, sizeof (int));
260 bin_pos
+= sizeof (int);
261 } else if (paramval
[0] >= '0' && paramval
[0] <= '9') {
263 for (x
= 1; x
< val_len
-1; x
++) {
264 if (!(paramval
[x
] >= '0' && paramval
[x
] <= '9')) {
265 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
270 int num
= atoi (paramval
);
272 //printf ("mov val digit = %d\n", num);
274 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
275 bin_pos
+= sizeof (int);
278 var_t
*var
= var_find (paramval
);
281 printf ("ERROR -> unknown mov variable '%s', line %d\n", paramval
, line
);
285 int num
= var
->offset
;
287 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
288 bin_pos
+= sizeof (int);
291 } else { /*MOV 32bit */
295 buffer_copy (bin_pos
, (void *) ®
, 1);
298 unsigned char regb
= 0;
300 if (!strncmp (paramreg
, "eax", 3)) {
301 if (!strncmp (paramval
, "eax", 3))
303 else if (!strncmp (paramval
, "ebx", 3))
305 else if (!strncmp (paramval
, "ecx", 3))
307 else if (!strncmp (paramval
, "edx", 3))
309 } else if (!strncmp (paramreg
, "ebx", 3)) {
310 if (!strncmp (paramval
, "eax", 3))
312 else if (!strncmp (paramval
, "ebx", 3))
314 else if (!strncmp (paramval
, "ecx", 3))
316 else if (!strncmp (paramval
, "edx", 3))
318 } else if (!strncmp (paramreg
, "ecx", 3)) {
319 if (!strncmp (paramval
, "eax", 3))
321 else if (!strncmp (paramval
, "ebx", 3))
323 else if (!strncmp (paramval
, "ecx", 3))
325 else if (!strncmp (paramval
, "edx", 3))
327 } else if (!strncmp (paramreg
, "edx", 3)) {
328 if (!strncmp (paramval
, "eax", 3))
330 else if (!strncmp (paramval
, "ebx", 3))
332 else if (!strncmp (paramval
, "ecx", 3))
334 else if (!strncmp (paramval
, "edx", 3))
338 buffer_copy (bin_pos
, (void *) ®b
, 1);
348 if (!strncmp ("cmp ", source
+i
, 4)) {
349 unsigned reg_len
= size
-i
-4;
350 char *paramreg
= source_paramfirst (source
+i
+4, ®_len
);
353 printf ("ERROR -> !paramreg\n");
357 unsigned val_len
= size
-reg_len
-i
-4;
358 char *paramval
= source_paramsecond (source
+i
+reg_len
+4, &val_len
);
361 printf ("ERROR -> !val_len\n");
365 i
+= source_nextline (source
+i
, size
-i
);
367 paramreg
[reg_len
] = '\0';
368 paramval
[val_len
] = '\0';
370 printf ("cmp: %s, %s\n", paramreg
, paramval
);
372 unsigned short reg
= 0;
375 if (paramval
[0] != 'e') { /* CMP 8bit/32bit */
376 if (paramreg
[0] == 'e' && paramreg
[1] == 'a' && paramreg
[2] == 'x') {
379 } else if (paramreg
[0] == 'e' && paramreg
[1] == 'b' && paramreg
[2] == 'x')
381 else if (paramreg
[0] == 'e' && paramreg
[1] == 'c' && paramreg
[2] == 'x')
383 else if (paramreg
[0] == 'e' && paramreg
[1] == 'd' && paramreg
[2] == 'x')
386 buffer_copy (bin_pos
, (void *) ®
, x
);
389 /* Let's convert parameter to binary number */
390 if (paramval
[0] == '\'') {
392 printf ("ERROR -> wrong parameter syntax - %d != 3, line: %d\n", val_len
, line
);
396 if (paramval
[2] != '\'' || paramval
[1] == '\'') {
397 printf ("ERROR -> wrong parameter syntax, line: %d\n", line
);
402 //printf ("mov val char = %c\n", c);
404 buffer_copy (bin_pos
, (void *) &c
, sizeof (int));
405 bin_pos
+= sizeof (int);
407 } else if (paramval
[0] == '0' && paramval
[1] == 'x') {
408 char *endptr
, *str
= paramval
+2;
410 long val
= strtol (str
, &endptr
, 16);
412 //printf ("mov val hexa = %d\n", val);
414 buffer_copy (bin_pos
, (void *) &val
, sizeof (int));
415 bin_pos
+= sizeof (int);
416 } else if (paramval
[0] >= '0' && paramval
[0] <= '9') {
418 for (x
= 1; x
< val_len
-1; x
++) {
419 if (!(paramval
[x
] >= '0' && paramval
[x
] <= '9')) {
420 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
425 int num
= atoi (paramval
);
427 //printf ("mov val digit = %d\n", num);
429 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
430 bin_pos
+= sizeof (int);
433 var_t
*var
= var_find (paramval
);
436 printf ("ERROR -> unknown mov variable '%s', line %d\n", paramval
, line
);
440 int num
= var
->offset
;
442 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
443 bin_pos
+= sizeof (int);
446 } else { /* CMP 32bit */
450 buffer_copy (bin_pos
, (void *) ®
, 1);
453 unsigned char regb
= 0;
455 if (!strncmp (paramreg
, "eax", 3)) {
456 if (!strncmp (paramval
, "eax", 3))
458 else if (!strncmp (paramval
, "ebx", 3))
460 else if (!strncmp (paramval
, "ecx", 3))
462 else if (!strncmp (paramval
, "edx", 3))
464 } else if (!strncmp (paramreg
, "ebx", 3)) {
465 if (!strncmp (paramval
, "eax", 3))
467 else if (!strncmp (paramval
, "ebx", 3))
469 else if (!strncmp (paramval
, "ecx", 3))
471 else if (!strncmp (paramval
, "edx", 3))
473 } else if (!strncmp (paramreg
, "ecx", 3)) {
474 if (!strncmp (paramval
, "eax", 3))
476 else if (!strncmp (paramval
, "ebx", 3))
478 else if (!strncmp (paramval
, "ecx", 3))
480 else if (!strncmp (paramval
, "edx", 3))
482 } else if (!strncmp (paramreg
, "edx", 3)) {
483 if (!strncmp (paramval
, "eax", 3))
485 else if (!strncmp (paramval
, "ebx", 3))
487 else if (!strncmp (paramval
, "ecx", 3))
489 else if (!strncmp (paramval
, "edx", 3))
493 buffer_copy (bin_pos
, (void *) ®b
, 1);
503 if (!strncmp ("int ", source
+i
, 4)) {
504 unsigned var
= size
-i
-4;
505 char *param
= source_param (source
+i
+4, &var
);
508 printf ("ERROR -> !param\n");
512 i
+= source_nextline (source
+i
, size
-i
);
514 unsigned char intr
= 0xcd; // int
515 buffer_copy (bin_pos
, (void *) &intr
, 1);
520 if (param
[0] == '0' && param
[1] == 'x') {
521 char *endptr
, *str
= param
+2;
523 long val
= strtol (str
, &endptr
, 16);
525 //printf ("int: 0x%x\n", val);
527 buffer_copy (bin_pos
, (void *) &val
, 1);
531 for (x
= 0; x
< var
; x
++) {
532 if (!isdigit (param
[x
])) {
533 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
538 int num
= atoi (param
);
540 buffer_copy (bin_pos
, (void *) &num
, 1);
544 printf ("int: %s\n", param
);
551 if (!strncmp ("jmp ", source
+i
, 4)) {
552 unsigned v
= size
-i
-4;
553 char *param
= source_param (source
+i
+4, &v
);
556 printf ("ERROR -> !param\n");
560 i
+= source_nextline (source
+i
, size
-i
);
562 unsigned char jmp
= 0xeb; // jmp
563 buffer_copy (bin_pos
, (void *) &jmp
, 1);
568 var_t
*var
= var_find (param
);
571 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
575 unsigned diff
= (bin_pos
- var
->offset
);
578 printf ("ERROR -> it is not 'near jump', line %d\n", line
);
582 unsigned char val
= 0xff - diff
;
584 buffer_copy (bin_pos
, (void *) &val
, 1);
587 printf ("jmp: %s\n", param
);
594 if (!strncmp ("jnz ", source
+i
, 4)) {
595 unsigned v
= size
-i
-4;
596 char *param
= source_param (source
+i
+4, &v
);
599 printf ("ERROR -> !param\n");
603 i
+= source_nextline (source
+i
, size
-i
);
605 unsigned char jmp
= 0x75; // jnz
606 buffer_copy (bin_pos
, (void *) &jmp
, 1);
611 var_t
*var
= var_find (param
);
614 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
618 unsigned diff
= (bin_pos
- var
->offset
);
621 printf ("ERROR -> it is not 'near jump not-zero', line %d\n", line
);
625 unsigned char val
= 0xff - diff
;
627 buffer_copy (bin_pos
, (void *) &val
, 1);
630 printf ("jnz: %s\n", param
);
637 if (!strncmp ("jz ", source
+i
, 3)) {
638 unsigned v
= size
-i
-3;
639 char *param
= source_param (source
+i
+3, &v
);
642 printf ("ERROR -> !param\n");
646 i
+= source_nextline (source
+i
, size
-i
);
648 unsigned char jmp
= 0x74; // jz
649 buffer_copy (bin_pos
, (void *) &jmp
, 1);
654 var_t
*var
= var_find (param
);
657 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
661 unsigned diff
= (bin_pos
- var
->offset
);
664 printf ("ERROR -> it is not 'near jump zero', line %d\n", line
);
668 unsigned char val
= 0xff - diff
;
670 buffer_copy (bin_pos
, (void *) &val
, 1);
673 printf ("jz: %s\n", param
);
680 if (!strncmp ("inc ", source
+i
, 4)) {
681 unsigned v
= size
-i
-4;
682 char *param
= source_param (source
+i
+4, &v
);
685 printf ("ERROR -> !param\n");
689 i
+= source_nextline (source
+i
, size
-i
);
694 printf ("ERROR -> inc: bad register name '%s', line %d\n", param
, line
);
698 unsigned char reg
= 0;
700 if (!strncmp (param
, "eax", 3))
702 else if (!strncmp (param
, "ebx", 3))
704 else if (!strncmp (param
, "ecx", 3))
706 else if (!strncmp (param
, "edx", 3))
709 buffer_copy (bin_pos
, (void *) ®
, 1);
712 printf ("inc: %s\n", param
);
719 if (!strncmp ("ret", source
+i
, 3)) {
720 if (!function_curr
) {
721 printf ("ERROR -> ret cannot be called out of function, line: %d\n", line
);
725 printf ("Function %s end on line %d\n", function_curr
->name
, line
);
729 unsigned char ret
= 0xc3;
730 buffer_copy (bin_pos
, (void *) &ret
, 1);
733 i
+= source_nextline (source
+i
, size
-i
);
740 if (!strncmp ("hlt", source
+i
, 3)) {
741 unsigned char hlt
= 0xf4;
742 buffer_copy (bin_pos
, (void *) &hlt
, 1);
745 i
+= source_nextline (source
+i
, size
-i
);
751 if ((source
[i
] >= 'a' && source
[i
] <= 'z') || (source
[i
] >= 'A' && source
[i
] <= 'Z')) {
754 for (y
= i
; y
< size
-i
; y
++) {
756 if (source
[y
] == ':') {
759 var_t
*var
= var_find (source
+i
);
762 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
766 printf ("Function '%s' on line %d\n", var
->name
, line
);
768 var
->offset
= bin_pos
;
770 function_curr
= var
; // set current function
775 if (source
[y
] == ' ' || source
[y
] == '\t' || source
[y
] == '\n' || source
[y
] == 32 || source
[y
] == ';') {
778 /* register db variable */
779 if (!strncmp (source
+y
, " db ", 4)) {
782 if (source
[i
+m
] == ' ')
787 var_t
*var
= var_create (VAR_TYPE_DB
, source
+i
, m
, (void *) 0x0 + i
, line
);
792 var
->offset
= data_pos
;
794 unsigned r
= source_nextline (source
+y
+4, size
-y
-4);
797 if (source
[y
+4] == '\'') {
800 if (source
[y
+6+k
] == '\'')
806 buffer_copy (data_pos
, (char *) source
+y
+5, k
+1);
809 if (source
[y
+7+k
] == ',') {
810 char *param
= source
+y
+8+k
;
812 /* jump over space */
818 if (!(param
[k
] >= 'a' && param
[k
] <= 'z') &&
819 !(param
[k
] >= 'A' && param
[k
] <= 'Z') &&
820 !(param
[k
] >= '0' && param
[k
] <= '9')) {
828 if (param
[0] == '0' && param
[1] == 'x') {
829 char *endptr2
, *str2
= param
+2;
831 long v
= strtol (str2
, &endptr2
, 16);
833 buffer_copy (data_pos
, (void *) &v
, 1);
837 for (x
= 0; x
< 4; x
++) {
838 if (!isdigit (param
[x
])) {
839 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
844 int num
= atoi (param
);
846 buffer_copy (data_pos
, (void *) &num
, 1);
852 printf ("ERROR -> db variable - wrong syntax, line: %d\n", line
);
861 printf ("ERROR -> unknown command '%s', line: %d\n", source
+i
, line
);
869 //if (source[i] != ' ' || source[i] != ';')
870 //printf ("ERROR -> unspecified character '%c', line: %d\n", source[i], line);
871 if (source
[i
] == ';') {
872 i
+= source_nextline (source
+i
, size
-i
);
878 if (source
[i
] == '\n')
885 char *source_open (char *file
, unsigned *size
)
887 int fd
= open (file
, O_RDONLY
);
890 printf ("error -> file '%s' not found !\n", file
);
894 char *buffer
= (char *) malloc (sizeof (char) * 10240);
897 printf ("ERROR -> out of memory !\n");
905 ret
= read (fd
, buffer
+l
, 512);
917 //printf ("Source: %s\n-=-=-=-=-=-=-=-=-\n\n", buffer);
924 var_list
.next
= &var_list
;
925 var_list
.prev
= &var_list
;