patterncMinor
Pretty printer for MMIX-assembly
Viewed 0 times
prettyassemblymmixprinterfor
Problem
I am currently writing a disassembler for Don Knuth's MMIX. The module in this gist is a pretty-printer for single instructions that reads in instructions from an
I am quite new to C. I would greatly appreciate any remarks on how this piece of code could be improved. I am especially concerned about stuff that won't work on common architectures other than x86(-64) or on other operating systems. As of now, I already asked the people freenode's
Tables shortened for brevity. See code pasted on GitHub for the rest.
pretty_print.c
```
#include
#include
#include "pretty_print.h"
const char *opcodes[256] = {
"trap","fcmp","fun","feql","fadd","fix","fsub","fixu", / 0x0# /
"flot","flot","flotu","flotu","sflot","sflot","sflotu","sflotu",
/ ... a lot more ... /
"jmp","jmp","pushj","pushj","geta","geta","put","put", / 0xF# /
"pop","resume","save","unsave","sync","swym","get","trip"
};
/* kinds of arguments and format strings
* S#: register number, e.g. $123
* #: 8-bit unsigned, e.g. #1F
* ##: the same, 16 Bit, e.g. #1337
* ###: the same, 24 Bit, e.g. #1F2E3D
F##: relative 16-bit adress, forwards, e.g.. @+4#1234
B##: the same, backwards, z.B. @-4#1234
* F###, B###: the same, 24 Bit
* R#: special register, z.B. rH
* ROUND: rounding mode, string contains comma
*/
enum op_type {
OP_SX_SY_SZ,
OP_SX_SY_Z,
OP_SX_Y_SZ,
OP_SX_Y_Z,
OP_X_SY_SZ,
OP_X_SY_Z,
/ OP_X_Y_SZ, /
/ OP_X_Y_Z, /
OP_SX_YZ,
OP_XYZ,
#define IS_SIMPLE_ARGF(x) ((x) \n",
[OP_SX_BYZ] = "$%hu,@-4*#%04" PRIx64" \n",
[OP_FXYZ] = "@+4*#%06" PRIx64" \n",
[OP_BXYZ]
char* buffer and prints the resulting disassembly to stdout. It is quite long, the code below is an excerpt of the most important parts.I am quite new to C. I would greatly appreciate any remarks on how this piece of code could be improved. I am especially concerned about stuff that won't work on common architectures other than x86(-64) or on other operating systems. As of now, I already asked the people freenode's
##c channel for help, they suggested me to use the new C99 syntax const char *opfstrings[] = { [OP_SX_SY_SZ] = ... , [OP_SX] = ... }and enums to avoid writing all those indices explicitly.Tables shortened for brevity. See code pasted on GitHub for the rest.
pretty_print.c
```
#include
#include
#include "pretty_print.h"
const char *opcodes[256] = {
"trap","fcmp","fun","feql","fadd","fix","fsub","fixu", / 0x0# /
"flot","flot","flotu","flotu","sflot","sflot","sflotu","sflotu",
/ ... a lot more ... /
"jmp","jmp","pushj","pushj","geta","geta","put","put", / 0xF# /
"pop","resume","save","unsave","sync","swym","get","trip"
};
/* kinds of arguments and format strings
* S#: register number, e.g. $123
* #: 8-bit unsigned, e.g. #1F
* ##: the same, 16 Bit, e.g. #1337
* ###: the same, 24 Bit, e.g. #1F2E3D
F##: relative 16-bit adress, forwards, e.g.. @+4#1234
B##: the same, backwards, z.B. @-4#1234
* F###, B###: the same, 24 Bit
* R#: special register, z.B. rH
* ROUND: rounding mode, string contains comma
*/
enum op_type {
OP_SX_SY_SZ,
OP_SX_SY_Z,
OP_SX_Y_SZ,
OP_SX_Y_Z,
OP_X_SY_SZ,
OP_X_SY_Z,
/ OP_X_Y_SZ, /
/ OP_X_Y_Z, /
OP_SX_YZ,
OP_XYZ,
#define IS_SIMPLE_ARGF(x) ((x) \n",
[OP_SX_BYZ] = "$%hu,@-4*#%04" PRIx64" \n",
[OP_FXYZ] = "@+4*#%06" PRIx64" \n",
[OP_BXYZ]
Solution
/* OP_X_Y_SZ, */
/* OP_X_Y_Z, */Commented out code is suspicious, it should probably just be removed.
#define IS_SIMPLE_ARGF(x) ((x) <= OP_XYZ)This is odd in the middle of an enum
case OP_SZ: printf(opfstrings[argf],(argf == OP_SX ? x : z)); break;I recommend splitting this across three lines to match the other cases.
while(count > 4) {
printOp(buffer,address);
buffer += 4;
address += 4;
count -= 4;
}I'd use a for loop.
Code Snippets
/* OP_X_Y_SZ, */
/* OP_X_Y_Z, */#define IS_SIMPLE_ARGF(x) ((x) <= OP_XYZ)case OP_SZ: printf(opfstrings[argf],(argf == OP_SX ? x : z)); break;while(count > 4) {
printOp(buffer,address);
buffer += 4;
address += 4;
count -= 4;
}Context
StackExchange Code Review Q#6006, answer score: 2
Revisions (0)
No revisions yet.