* © 2018 Aaron Taylor <ataylor at subgeniuskitty dot com>
* See LICENSE.txt file for copyright and license details.
#define WIDTH_MNEMONICS 14
* 10 characters for address in hexadecimal
* 10 characters for hex dump of 32-bit word
* 40 characters for binary representation of 32-bit word
* remainder of line for mnemonics
printf(" Offset || Hex || Binary "
"============================================================"
"============================================================"
"===================\n");
print_usage(char ** argv
)
printf( "NED Disassembler v%d (www.subgeniuskitty.com)\n"
" -h Help (prints this message)\n"
" -i <file> Specify a binary image file to disassemble.\n"
print_formatA_binary(uint32_t word
)
for (int bit_index
= 30; bit_index
>= 0; bit_index
--) {
/* Insert space every 8 bits. Leading space is intentional. */
if ((chunk_length
++ % 8) == 0) printf(" ");
if ((word
>> bit_index
) & 0b1) {
print_formatA_mnemonics(uint32_t word
)
printf("WORD =====>%n", &position
);
while (position
++ != WIDTH_MNEMONICS
) printf(" ");
printf("0x%x%n", ((word
& 0b01111111111111111111111111111111) << 1), &position
);
while (position
++ != WIDTH_MNEMONICS
) printf(" ");
printf("0%o%n", ((word
& 0b01111111111111111111111111111111) << 1), &position
);
while (position
++ != WIDTH_MNEMONICS
) printf(" ");
printf("%u%n", ((word
& 0b01111111111111111111111111111111) << 1), &position
);
while (position
++ != WIDTH_MNEMONICS
) printf(" ");
extract_syllable_from_word(uint32_t word
, uint8_t index
)
uint32_t mask
= 0b111111 << 6*(4-index
);
return (word
& mask
) >> 6*(4-index
);
print_formatC_binary(uint32_t word
)
for (int syllable_index
= 0; syllable_index
< 5; syllable_index
++) {
uint8_t syllable
= extract_syllable_from_word(word
, syllable_index
);
for (int i
= 5; i
>= 0; i
--) {
if (((syllable
>> i
) & 0b1) == 1) {
print_formatC_mnemonics(uint32_t word
)
for (int syllable_index
= 0; syllable_index
< 5; syllable_index
++) {
uint8_t syllable
= extract_syllable_from_word(word
, syllable_index
);
if (syllable
& 0b100000) { /* Check the first bit of the syllable. 1 means IM_x. */
printf("IM_%d%n", (syllable
& 0b11111), &position
);
} else if (syllable
& 0b10000) { /* 1 in 2nd bit means LDSP+x or STSP+x instruction. */
if (syllable
& 0b1000) { /* LDSP+x */
printf("LDSP+%d%n", (syllable
& 0b111), &position
);
printf("STSP+%d%n", (syllable
& 0b111), &position
);
case AND
: printf("AND%n", &position
); break;
case OR
: printf("OR%n", &position
); break;
case NOT
: printf("NOT%n", &position
); break;
case XOR
: printf("XOR%n", &position
); break;
case ADD
: printf("ADD%n", &position
); break;
case MVSTCK
: printf("MVSTCK%n", &position
); break;
case SHIFT
: printf("SHIFT%n", &position
); break;
case CMPSWP
: printf("CMPSWP%n", &position
); break;
case TEST
: printf("TEST%n", &position
); break;
case BRZ
: printf("BRZ%n", &position
); break;
case LOAD
: printf("LOAD%n", &position
); break;
case STORE
: printf("STORE%n", &position
); break;
case NOP
: printf("NOP%n", &position
); break;
case HALT
: printf("HALT%n", &position
); break;
case JMP
: printf("JMP%n", &position
); break;
case SWAP
: printf("SWAP%n", &position
); break;
default: printf("?ERR?%n", &position
); break;
while (position
++ != WIDTH_MNEMONICS
) printf(" ");
main(int argc
, char ** argv
)
* Process command line arguments
while ((c
= getopt(argc
,argv
,"i:h")) != -1) {
if ((input
= fopen(optarg
, "r")) == NULL
) {
fprintf(stderr
, "ERROR: %s: %s\n", optarg
, strerror(errno
));
fprintf(stderr
, "ERROR: Must specify a binary image file with -i flag.\n");
/* Since all NED instructions are one word (4 bytes) wide, read in one word increments. */
while (fread(&word
, 4, 1, input
)) {
printf("0x%08x", offset
);
if (word
& (0b1 << 31)) { /* Format A instruction word */
print_formatA_binary(word
);
print_formatA_mnemonics(word
);
} else if ((word
& (0b11 << 30)) == 0) { /* Format C instruction word */
print_formatC_binary(word
);
print_formatC_mnemonics(word
);
fprintf(stderr
, "ERROR: Malformed instruction word: %o\n", word
);
offset
+= 4; /* Increment by one word (4 bytes). */