oriansj/stage0

M0-macro.s NULL pointer dereference in 16 bit mode

Closed this issue · 2 comments

In developing knightpies I found issues running M0-macro.s in 16 bit and 64 bit mode. I used stage0/High_level_prototypes/defs plus smaller .s files such as stage_monitor.s as input. In 32 bit mode I was able to process these with 48k of memory.

I suspected the issue was that program memory was being written to. So, similar to the outside_of_world guard, I started implementing inside_of_world to test for write inside of program memory or instruction reads outside of program memory.
https://github.com/markjenkins/knightpies/compare/readonlyprogrammem

This showed null pointer dereference at places such as STORE32 R2 R4 12 (0x2b0 ) in setExpression when combined with stage0 Release_0.4.0 .

I've found the same result by checking for NULL pointer when STORE32 is called in the stage0 C emulator.
master...markjenkins:M0nullpointerbug

A simple JUMP.Z guard at the start of setExpression can allow M0-macro to run in 16 bit mode, but the output ends up corrupted, and in any event, R13 shouldn't be NULL on the first iteration through Line_Macro_0 .

I'm going to be looking into this. Part of what I'll do is improve my optional program area guard code for inappropriate read and write accesses in both the knightpies and stage0 implementations. At this point I can't yet say if this is an assembler bug or emulator implementation bug common to knightpies and stage0. I am seeing less issues with stage0 Release_0.4.0 than Release_0.2.0.

I'm interested in contributing to 16 bit support. It helps me test knightpies more vigorously and challenges my assumptions about these instructions, particularly especially when I write register size optimized versions of the instructions and compare. I also like the idea of seeing a 16 bit knight machine constructed at some point due to the lower TTL count vs 32 bit. I appreciate this will require a rewrite of M0-macro.s and cc_knight-native.s to support larger inputs and a low memory rewrite will be a more challenging for people to read. In my mind, better to support this with a separate M0-macro-lowmem.s and cc_knight-native_lowmem.s than not at all. That this is possible in a 16bit address space in two passes with only things like symbol and struct definition tables being there in the first pass is something makes C a cool language.

But in any event, M0-macro.s as it is currently written should be able to operate in a 16 bit address space with small inputs seeing how it works fine in 32 bit mode with 48K memory and small inputs.

Ah, thanks for the comments in chat. There are LOAD32 instructions in M0-macro.s, you can't load 32 bits into a 16 bit register. My ooops! (Though I'm thinking storing 16 bit registers into 32 bits of memory per STORE32 should be okay).

I still have to wrap my head around LOAD32 and STORE32 in a 64 bit context. I could edit the title of this issue to keep the 64 bit mystery open or perhaps open new issue if I have more than master...markjenkins:M0nullpointerbug to make my case.

LOAD32 is sign extended, so that's why it doesn't work in a 64bit context. Both things raised are wishlist issues and not bugs in current implementation at assembler or emulator level, so closing the issue.