c4 icon indicating copy to clipboard operation
c4 copied to clipboard

Assembly (-s) listing of branches and jumps is incorrect

Open cardiffman opened this issue 7 years ago • 2 comments

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.

cardiffman avatar Jul 09 '17 09:07 cardiffman

Thank you for pointing this out.

rswier avatar Jul 10 '17 04:07 rswier

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.

andrakis avatar Jun 29 '19 03:06 andrakis