1 /* asmconv 1.11 - convert 80X86 assembly Author: Kees J. Bot
4 static char version
[] = "1.11";
15 #include "languages.h"
17 void fatal(char *label
)
19 fprintf(stderr
, "asmconv: %s: %s\n", label
, strerror(errno
));
23 void *allocate(void *mem
, size_t size
)
24 /* A checked malloc/realloc(). Yes, I know ISO C allows realloc(NULL, size). */
26 mem
= mem
== nil
? malloc(size
) : realloc(mem
, size
);
27 if (mem
== nil
) fatal("malloc()");
31 void deallocate(void *mem
)
32 /* Free a malloc()d cell. (Yes I know ISO C allows free(NULL) */
34 if (mem
!= nil
) free(mem
);
37 char *copystr(const char *s
)
41 c
= allocate(nil
, (strlen(s
) + 1) * sizeof(s
[0]));
46 int isanumber(const char *s
)
47 /* True if s can be turned into a number. */
51 (void) strtol(s
, &end
, 0);
52 return end
!= s
&& *end
== 0;
55 /* "Invisible" globals. */
56 int asm_mode32
= (sizeof(int) == 4);
57 int err_code
= EXIT_SUCCESS
;
59 int main(int argc
, char **argv
)
61 void (*parse_init
)(char *file
);
62 asm86_t
*(*get_instruction
)(void);
63 void (*emit_init
)(char *file
, const char *banner
);
64 void (*emit_instruction
)(asm86_t
*instr
);
65 char *lang_parse
, *lang_emit
, *input_file
, *output_file
;
69 if (argc
> 1 && argv
[1][0] == '-' && argv
[1][1] == 'm') {
70 if (strcmp(argv
[1], "-mi86") == 0) {
73 if (strcmp(argv
[1], "-mi386") == 0) {
76 fprintf(stderr
, "asmconv: '%s': unknown machine\n",
83 if (argc
< 3 || argc
> 5) {
85 "Usage: asmconv <input-type> <output-type> [input-file [output-file]]\n");
91 input_file
= argc
< 4 ? nil
: argv
[3];
92 output_file
= argc
< 5 ? nil
: argv
[4];
94 /* Choose the parsing routines. */
95 if (strcmp(lang_parse
, "ack") == 0) {
97 parse_init
= ack_parse_init
;
98 get_instruction
= ack_get_instruction
;
100 if (strcmp(lang_parse
, "ncc") == 0) {
101 /* ACK Xenix assembly, a black sheep among ACK assemblies. */
102 parse_init
= ncc_parse_init
;
103 get_instruction
= ncc_get_instruction
;
105 if (strcmp(lang_parse
, "gnu") == 0) {
106 /* GNU assembly. Parser by R.S. Veldema. */
107 parse_init
= gnu_parse_init
;
108 get_instruction
= gnu_get_instruction
;
110 if (strcmp(lang_parse
, "bas") == 0) {
111 /* Bruce Evans' assembler. */
112 parse_init
= bas_parse_init
;
113 get_instruction
= bas_get_instruction
;
115 fprintf(stderr
, "asmconv: '%s': unknown input language\n",
120 /* Choose the output language. */
121 if (strcmp(lang_emit
, "ack") == 0) {
123 emit_init
= ack_emit_init
;
124 emit_instruction
= ack_emit_instruction
;
126 if (strcmp(lang_emit
, "ncc") == 0) {
127 /* ACK Xenix assembly, can be read by BAS and the 8086 ACK
128 * ANSI C compiler. (Allows us to compile the Boot Monitor.)
130 emit_init
= ncc_emit_init
;
131 emit_instruction
= ncc_emit_instruction
;
133 if (strcmp(lang_emit
, "gnu") == 0) {
134 /* GNU assembler. So we can assemble the ACK stuff among the
135 * kernel sources and in the library.
137 emit_init
= gnu_emit_init
;
138 emit_instruction
= gnu_emit_instruction
;
140 fprintf(stderr
, "asmconv: '%s': unknown output language\n",
145 sprintf(banner
, "Translated from %s to %s by asmconv %s",
146 lang_parse
, lang_emit
, version
);
148 (*parse_init
)(input_file
);
149 (*emit_init
)(output_file
, banner
);
151 instr
= (*get_instruction
)();
152 (*emit_instruction
)(instr
);
153 if (instr
== nil
) break;