c4
c4 copied to clipboard
Assembly (-s) listing of branches and jumps is incorrect
If you build and do this:
./c4 -s c4.c | tail -20 | head -5
You will see
LI
LEV
525: else { printf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1; }
JMP 0
IMM -2357464
But when this is executed using the -d option you of course don't have crashes from branching to zero, and the instructions show non-zero targets in every executed case.
I believe the root cause is printing the assembly from inside next()
from where it will often be the case that the code starting at line 291 in stmt() will not have back-patched the branches:
if (tk == ')') next(); else { printf("%d: close paren expected\n", line); exit(-1); }
*++e = BZ; b = ++e;
stmt();
The recursive call to stmt() calls next() eventually, which prints the instructions that have not yet been printed, i.e. while (le < e)
, and this includes the byte at b
which is to be filled in later.
At the moment I believe there is a fairly economical approach to this, but it would involve postponing the entire listing to after the parse, with some sort of list of (source_line,object) pairs or array of source lines so the C and assembly can be interleaved, with perhaps an atexit() to provide the listing if the parse aborts.
Thank you for pointing this out.
If anyone is still interested, I did something to this effect in a variation of my own c4.c. It's not trivial, and my solution probably could be improved upon, but it does do what is suggested - print out the source after compilation is complete.
It is not an elegant solution, and I don't think it should be merged into here. But it might give people some insight into how to fix this issue.