3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
35 var_t
*var_find (char *name
)
39 for (var
= var_list
.next
; var
!= &var_list
; var
= var
->next
) {
40 if (!strcmp (var
->name
, name
))
47 var_t
*var_create (char type
, char *name
, unsigned len
, void *address
, unsigned line
)
51 /* alloc and init context */
52 var
= (var_t
*) malloc (sizeof (var_t
));
59 var
->name
= (char *) malloc (sizeof (char) * (len
+ 1));
64 memcpy (var
->name
, name
, len
);
65 var
->name
[len
] = '\0';
67 var
->address
= address
;
71 var
->next
= &var_list
;
72 var
->prev
= var_list
.prev
;
73 var
->prev
->next
= var
;
74 var
->next
->prev
= var
;
76 printf ("var_create () -> '%s' on line %d\n", var
->name
, line
);
81 int source_nextline (char *source
, unsigned size
)
85 for (i
= 0; i
< size
; i
++) {
86 //printf ("znak: %c : %d\n", source[i], source[i]);
87 if (source
[i
] == '\n') {
88 //printf ("source_nextline: %d\n", i);
96 char *source_param (char *source
, unsigned *size
)
99 char *param
= (char *) 0;
100 unsigned len
= *size
;
102 for (i
= 0; i
< len
; i
++) {
104 if (source
[i
] == ' ' || source
[i
] == '\t') {
109 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
110 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
111 (source
[i
] >= '0' && source
[i
] <= '9'))
113 } else if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == '\n' || source
[i
] == ';') {
122 char *source_paramfirst (char *source
, unsigned *size
)
125 char *param
= (char *) 0;
126 unsigned len
= *size
;
128 for (i
= 0; i
< len
; i
++) {
130 if (source
[i
] == ' ' || source
[i
] == '\t')
133 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
134 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
135 (source
[i
] >= '0' && source
[i
] <= '9'))
137 } else if (source
[i
] == ' ' || source
[i
] == ',' || source
[i
] == '\t') {
146 char *source_paramsecond (char *source
, unsigned *size
)
149 char *param
= (char *) 0;
150 unsigned len
= *size
;
152 for (i
= 0; i
< len
; i
++) {
154 if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == ',')
157 if ((source
[i
] >= 'a' && source
[i
] <= 'z') ||
158 (source
[i
] >= 'A' && source
[i
] <= 'Z') ||
159 (source
[i
] >= '0' && source
[i
] <= '9'))
161 else if (source
[i
] == '\'')
163 } else if (source
[i
] == ' ' || source
[i
] == '\t' || source
[i
] == '\n' || source
[i
] == ';') {
172 int source_parse (char *source
, unsigned size
)
177 for (i
= 0; i
< size
; i
++) {
179 if (!strncmp ("global ", source
+i
, 7)) {
180 unsigned var
= size
-i
-7;
181 char *param
= source_param (source
+i
+7, &var
);
184 printf ("ERROR -> !param\n");
188 var_create (VAR_TYPE_GLOBAL
, param
, var
, (void *) 0x0 + i
, line
);
190 i
+= source_nextline (source
+i
, size
-i
);
197 if (!strncmp ("mov ", source
+i
, 4)) {
198 unsigned reg_len
= size
-i
-4;
199 char *paramreg
= source_paramfirst (source
+i
+4, ®_len
);
202 printf ("ERROR -> !paramreg\n");
206 unsigned val_len
= size
-reg_len
-i
-4;
207 char *paramval
= source_paramsecond (source
+i
+reg_len
+4, &val_len
);
210 printf ("ERROR -> !val_len\n");
214 i
+= source_nextline (source
+i
, size
-i
);
216 paramreg
[reg_len
] = '\0';
217 paramval
[val_len
] = '\0';
219 printf ("mov: %s, %s\n", paramreg
, paramval
);
221 unsigned char reg
= 0;
223 if (paramval
[0] != 'e') { /* MOV 8bit/32bit */
224 if (paramreg
[0] == 'e' && paramreg
[1] == 'a' && paramreg
[2] == 'x')
226 else if (paramreg
[0] == 'e' && paramreg
[1] == 'b' && paramreg
[2] == 'x')
228 else if (paramreg
[0] == 'e' && paramreg
[1] == 'c' && paramreg
[2] == 'x')
230 else if (paramreg
[0] == 'e' && paramreg
[1] == 'd' && paramreg
[2] == 'x')
233 buffer_copy (bin_pos
, (void *) ®
, 1);
236 /* Let's convert parameter to binary number */
237 if (paramval
[0] == '\'') {
239 printf ("ERROR -> wrong parameter syntax - %d != 3, line: %d\n", val_len
, line
);
243 if (paramval
[2] != '\'' || paramval
[1] == '\'') {
244 printf ("ERROR -> wrong parameter syntax, line: %d\n", line
);
249 //printf ("mov val char = %c\n", c);
251 buffer_copy (bin_pos
, (void *) &c
, sizeof (int));
252 bin_pos
+= sizeof (int);
254 } else if (paramval
[0] == '0' && paramval
[1] == 'x') {
255 char *endptr
, *str
= paramval
+2;
257 long val
= strtol (str
, &endptr
, 16);
259 //printf ("mov val hexa = %d\n", val);
261 buffer_copy (bin_pos
, (void *) &val
, sizeof (int));
262 bin_pos
+= sizeof (int);
263 } else if (paramval
[0] >= '0' && paramval
[0] <= '9') {
265 for (x
= 1; x
< val_len
-1; x
++) {
266 if (!(paramval
[x
] >= '0' && paramval
[x
] <= '9')) {
267 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
272 int num
= atoi (paramval
);
274 //printf ("mov val digit = %d\n", num);
276 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
277 bin_pos
+= sizeof (int);
280 var_t
*var
= var_find (paramval
);
283 printf ("ERROR -> unknown mov variable '%s', line %d\n", paramval
, line
);
287 unsigned num
= (unsigned) var
->offset
+ 0x800000;
289 buffer_copy (bin_pos
, (void *) &num
, sizeof (unsigned));
290 bin_pos
+= sizeof (unsigned);
293 } else { /*MOV 32bit */
297 buffer_copy (bin_pos
, (void *) ®
, 1);
300 unsigned char regb
= 0;
302 if (!strncmp (paramreg
, "eax", 3)) {
303 if (!strncmp (paramval
, "eax", 3))
305 else if (!strncmp (paramval
, "ebx", 3))
307 else if (!strncmp (paramval
, "ecx", 3))
309 else if (!strncmp (paramval
, "edx", 3))
311 } else if (!strncmp (paramreg
, "ebx", 3)) {
312 if (!strncmp (paramval
, "eax", 3))
314 else if (!strncmp (paramval
, "ebx", 3))
316 else if (!strncmp (paramval
, "ecx", 3))
318 else if (!strncmp (paramval
, "edx", 3))
320 } else if (!strncmp (paramreg
, "ecx", 3)) {
321 if (!strncmp (paramval
, "eax", 3))
323 else if (!strncmp (paramval
, "ebx", 3))
325 else if (!strncmp (paramval
, "ecx", 3))
327 else if (!strncmp (paramval
, "edx", 3))
329 } else if (!strncmp (paramreg
, "edx", 3)) {
330 if (!strncmp (paramval
, "eax", 3))
332 else if (!strncmp (paramval
, "ebx", 3))
334 else if (!strncmp (paramval
, "ecx", 3))
336 else if (!strncmp (paramval
, "edx", 3))
340 buffer_copy (bin_pos
, (void *) ®b
, 1);
350 if (!strncmp ("cmp ", source
+i
, 4)) {
351 unsigned reg_len
= size
-i
-4;
352 char *paramreg
= source_paramfirst (source
+i
+4, ®_len
);
355 printf ("ERROR -> !paramreg\n");
359 unsigned val_len
= size
-reg_len
-i
-4;
360 char *paramval
= source_paramsecond (source
+i
+reg_len
+4, &val_len
);
363 printf ("ERROR -> !val_len\n");
367 i
+= source_nextline (source
+i
, size
-i
);
369 paramreg
[reg_len
] = '\0';
370 paramval
[val_len
] = '\0';
372 printf ("cmp: %s, %s\n", paramreg
, paramval
);
374 unsigned short reg
= 0;
377 if (paramval
[0] != 'e') { /* CMP 8bit/32bit */
378 if (paramreg
[0] == 'e' && paramreg
[1] == 'a' && paramreg
[2] == 'x') {
381 } else if (paramreg
[0] == 'e' && paramreg
[1] == 'b' && paramreg
[2] == 'x')
383 else if (paramreg
[0] == 'e' && paramreg
[1] == 'c' && paramreg
[2] == 'x')
385 else if (paramreg
[0] == 'e' && paramreg
[1] == 'd' && paramreg
[2] == 'x')
388 buffer_copy (bin_pos
, (void *) ®
, x
);
391 /* Let's convert parameter to binary number */
392 if (paramval
[0] == '\'') {
394 printf ("ERROR -> wrong parameter syntax - %d != 3, line: %d\n", val_len
, line
);
398 if (paramval
[2] != '\'' || paramval
[1] == '\'') {
399 printf ("ERROR -> wrong parameter syntax, line: %d\n", line
);
404 //printf ("mov val char = %c\n", c);
406 buffer_copy (bin_pos
, (void *) &c
, sizeof (int));
407 bin_pos
+= sizeof (int);
409 } else if (paramval
[0] == '0' && paramval
[1] == 'x') {
410 char *endptr
, *str
= paramval
+2;
412 long val
= strtol (str
, &endptr
, 16);
414 //printf ("mov val hexa = %d\n", val);
416 buffer_copy (bin_pos
, (void *) &val
, sizeof (int));
417 bin_pos
+= sizeof (int);
418 } else if (paramval
[0] >= '0' && paramval
[0] <= '9') {
420 for (x
= 1; x
< val_len
-1; x
++) {
421 if (!(paramval
[x
] >= '0' && paramval
[x
] <= '9')) {
422 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
427 int num
= atoi (paramval
);
429 //printf ("mov val digit = %d\n", num);
431 buffer_copy (bin_pos
, (void *) &num
, sizeof (int));
432 bin_pos
+= sizeof (int);
435 var_t
*var
= var_find (paramval
);
438 printf ("ERROR -> unknown mov variable '%s', line %d\n", paramval
, line
);
442 unsigned num
= (unsigned) var
->offset
+ 0x800000;
444 buffer_copy (bin_pos
, (void *) &num
, sizeof (unsigned));
445 bin_pos
+= sizeof (unsigned);
448 } else { /* CMP 32bit */
452 buffer_copy (bin_pos
, (void *) ®
, 1);
455 unsigned char regb
= 0;
457 if (!strncmp (paramreg
, "eax", 3)) {
458 if (!strncmp (paramval
, "eax", 3))
460 else if (!strncmp (paramval
, "ebx", 3))
462 else if (!strncmp (paramval
, "ecx", 3))
464 else if (!strncmp (paramval
, "edx", 3))
466 } else if (!strncmp (paramreg
, "ebx", 3)) {
467 if (!strncmp (paramval
, "eax", 3))
469 else if (!strncmp (paramval
, "ebx", 3))
471 else if (!strncmp (paramval
, "ecx", 3))
473 else if (!strncmp (paramval
, "edx", 3))
475 } else if (!strncmp (paramreg
, "ecx", 3)) {
476 if (!strncmp (paramval
, "eax", 3))
478 else if (!strncmp (paramval
, "ebx", 3))
480 else if (!strncmp (paramval
, "ecx", 3))
482 else if (!strncmp (paramval
, "edx", 3))
484 } else if (!strncmp (paramreg
, "edx", 3)) {
485 if (!strncmp (paramval
, "eax", 3))
487 else if (!strncmp (paramval
, "ebx", 3))
489 else if (!strncmp (paramval
, "ecx", 3))
491 else if (!strncmp (paramval
, "edx", 3))
495 buffer_copy (bin_pos
, (void *) ®b
, 1);
505 if (!strncmp ("int ", source
+i
, 4)) {
506 unsigned var
= size
-i
-4;
507 char *param
= source_param (source
+i
+4, &var
);
510 printf ("ERROR -> !param\n");
514 i
+= source_nextline (source
+i
, size
-i
);
516 unsigned char intr
= 0xcd; // int
517 buffer_copy (bin_pos
, (void *) &intr
, 1);
522 if (param
[0] == '0' && param
[1] == 'x') {
523 char *endptr
, *str
= param
+2;
525 long val
= strtol (str
, &endptr
, 16);
527 //printf ("int: 0x%x\n", val);
529 buffer_copy (bin_pos
, (void *) &val
, 1);
533 for (x
= 0; x
< var
; x
++) {
534 if (!isdigit (param
[x
])) {
535 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
540 int num
= atoi (param
);
542 buffer_copy (bin_pos
, (void *) &num
, 1);
546 printf ("int: %s\n", param
);
553 if (!strncmp ("jmp ", source
+i
, 4)) {
554 unsigned v
= size
-i
-4;
555 char *param
= source_param (source
+i
+4, &v
);
558 printf ("ERROR -> !param\n");
562 i
+= source_nextline (source
+i
, size
-i
);
564 unsigned char jmp
= 0xeb; // jmp
565 buffer_copy (bin_pos
, (void *) &jmp
, 1);
570 var_t
*var
= var_find (param
);
573 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
577 unsigned diff
= (bin_pos
- var
->offset
);
580 printf ("ERROR -> it is not 'near jump', line %d\n", line
);
584 unsigned char val
= 0xff - diff
;
586 buffer_copy (bin_pos
, (void *) &val
, 1);
589 printf ("jmp: %s\n", param
);
596 if (!strncmp ("jnz ", source
+i
, 4)) {
597 unsigned v
= size
-i
-4;
598 char *param
= source_param (source
+i
+4, &v
);
601 printf ("ERROR -> !param\n");
605 i
+= source_nextline (source
+i
, size
-i
);
607 unsigned char jmp
= 0x75; // jnz
608 buffer_copy (bin_pos
, (void *) &jmp
, 1);
613 var_t
*var
= var_find (param
);
616 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
620 unsigned diff
= (bin_pos
- var
->offset
);
623 printf ("ERROR -> it is not 'near jump not-zero', line %d\n", line
);
627 unsigned char val
= 0xff - diff
;
629 buffer_copy (bin_pos
, (void *) &val
, 1);
632 printf ("jnz: %s\n", param
);
639 if (!strncmp ("jz ", source
+i
, 3)) {
640 unsigned v
= size
-i
-3;
641 char *param
= source_param (source
+i
+3, &v
);
644 printf ("ERROR -> !param\n");
648 i
+= source_nextline (source
+i
, size
-i
);
650 unsigned char jmp
= 0x74; // jz
651 buffer_copy (bin_pos
, (void *) &jmp
, 1);
656 var_t
*var
= var_find (param
);
659 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
663 unsigned diff
= (bin_pos
- var
->offset
);
666 printf ("ERROR -> it is not 'near jump zero', line %d\n", line
);
670 unsigned char val
= 0xff - diff
;
672 buffer_copy (bin_pos
, (void *) &val
, 1);
675 printf ("jz: %s\n", param
);
682 if (!strncmp ("inc ", source
+i
, 4)) {
683 unsigned v
= size
-i
-4;
684 char *param
= source_param (source
+i
+4, &v
);
687 printf ("ERROR -> !param\n");
691 i
+= source_nextline (source
+i
, size
-i
);
696 printf ("ERROR -> inc: bad register name '%s', line %d\n", param
, line
);
700 unsigned char reg
= 0;
702 if (!strncmp (param
, "eax", 3))
704 else if (!strncmp (param
, "ebx", 3))
706 else if (!strncmp (param
, "ecx", 3))
708 else if (!strncmp (param
, "edx", 3))
711 buffer_copy (bin_pos
, (void *) ®
, 1);
714 printf ("inc: %s\n", param
);
721 if (!strncmp ("ret", source
+i
, 3)) {
722 if (!function_curr
) {
723 printf ("ERROR -> ret cannot be called out of function, line: %d\n", line
);
727 printf ("Function %s end on line %d\n", function_curr
->name
, line
);
731 unsigned char ret
= 0xc3;
732 buffer_copy (bin_pos
, (void *) &ret
, 1);
735 i
+= source_nextline (source
+i
, size
-i
);
742 if (!strncmp ("hlt", source
+i
, 3)) {
743 unsigned char hlt
= 0xf4;
744 buffer_copy (bin_pos
, (void *) &hlt
, 1);
747 i
+= source_nextline (source
+i
, size
-i
);
753 if ((source
[i
] >= 'a' && source
[i
] <= 'z') || (source
[i
] >= 'A' && source
[i
] <= 'Z')) {
756 for (y
= i
; y
< size
-i
; y
++) {
758 if (source
[y
] == ':') {
761 var_t
*var
= var_find (source
+i
);
764 printf ("ERROR -> unknown variable '%s', line %d\n", source
+i
, line
);
768 printf ("Function '%s' on line %d\n", var
->name
, line
);
770 var
->offset
= bin_pos
;
772 function_curr
= var
; // set current function
776 if (source
[y
] == ' ' || source
[y
] == '\t' || source
[y
] == '\n' || source
[y
] == 32 || source
[y
] == ';') {
777 /* register db variable */
778 if (!strncmp (source
+y
, " db ", 4)) {
781 if (source
[i
+m
] == ' ')
786 var_t
*var
= var_create (VAR_TYPE_DB
, source
+i
, m
, (void *) 0x0 + i
, line
);
791 var
->offset
= data_pos
;
793 unsigned r
= source_nextline (source
+y
+4, size
-y
-4);
796 if (source
[y
+4] == '\'') {
799 if (source
[y
+6+k
] == '\'')
805 buffer_copy (data_pos
, (char *) source
+y
+5, k
+1);
808 if (source
[y
+7+k
] == ',') {
809 char *param
= source
+y
+8+k
;
811 /* jump over space */
817 if (!(param
[k
] >= 'a' && param
[k
] <= 'z') &&
818 !(param
[k
] >= 'A' && param
[k
] <= 'Z') &&
819 !(param
[k
] >= '0' && param
[k
] <= '9')) {
827 if (param
[0] == '0' && param
[1] == 'x') {
828 char *endptr2
, *str2
= param
+2;
830 long v
= strtol (str2
, &endptr2
, 16);
832 buffer_copy (data_pos
, (void *) &v
, 1);
836 for (x
= 0; x
< 4; x
++) {
837 if (!isdigit (param
[x
])) {
838 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line
);
843 int num
= atoi (param
);
845 buffer_copy (data_pos
, (void *) &num
, 1);
851 printf ("ERROR -> db variable - wrong syntax, line: %d\n", line
);
860 printf ("ERROR -> unknown command '%s', line: %d\n", source
+i
, line
);
868 //if (source[i] != ' ' || source[i] != ';')
869 //printf ("ERROR -> unspecified character '%c', line: %d\n", source[i], line);
870 if (source
[i
] == ';') {
871 i
+= source_nextline (source
+i
, size
-i
);
877 if (source
[i
] == '\n')
884 char *source_open (char *file
, unsigned *size
)
886 /* int fd = open (file, O_RDONLY);
889 printf ("error -> file '%s' not found !\n", file);
893 char *buffer = (char *) malloc (sizeof (char) * 10240);
896 printf ("ERROR -> out of memory !\n");
904 ret = read (fd, buffer+l, 512);
916 printf ("Source: %s\n-=-=-=-=-=-=-=-=-\n\n", buffer);*/
918 FILE *f
= fopen (file
, "r");
921 printf ("error -> file '%s' not found !\n", file
);
925 fseek (f
, 0, SEEK_END
);
926 unsigned flen
= ftell (f
);
927 fseek (f
, 0, SEEK_SET
);
931 char *buffer
= (char *) malloc (sizeof (char) * flen
+ 1);
934 printf ("ERROR -> out of memory !\n");
938 fread (buffer
, flen
, 1, f
);
947 var_list
.next
= &var_list
;
948 var_list
.prev
= &var_list
;