DCPUTeam / DCPUToolchain

[ARCHIVED] The code repository for the DCPU-16 Toolchain.
http://dcputoolcha.in/
MIT License
96 stars 14 forks source link

Invalid assembly generated, or bad stack frame? #91

Closed kierenj closed 12 years ago

kierenj commented 12 years ago

Hi, I think I have a bug, but am not sure.

At the point of hitting line 7, Y (which I guess is a mirror of the stack for local variables?) is set to 0. This means that memory at [0] is overwritten. Basically, after _stack_caller_init is run, at least for the first time, Y is 0.

It runs and works, but I would think that the initial stack frame has an OBOE or similar?

Source code:

int main()
{
    int screen = 0x8000;       // this is line 7
    *screen = 'A' + (0xf000);
    return 0;
}
.ULINE 7 "C:\Users\Kieren\Documents\GeneralTests\untitled.c"
    SET A, 32768

    SET I, Y
    SET [I], A

.ULINE 8 "C:\Users\Kieren\Documents\GeneralTests\untitled.c"
hach-que commented 12 years ago

Y should definitely not be 0.

It's a stack pointer that points to the start of the function parameters and local variables, with the return value and previous Y being stored just behind it. The reason we do this is so that SP can still point to the proper end of the stack, where empty space is (so that assembly calls that use SP won't corrupt anything).

On a side note, this is almost certainly why we're having issues with running code linked from multiple C files.

kierenj commented 12 years ago

It could be the emulator I'm using processing the stack helper functions incorrectly, but I don't think so (I've stepped through them and can't see an instruction going awry - but I may have missed something). I'll post another comment if I find any more detail

hach-que commented 12 years ago

Given that I changed the bootstrap system right before releasing beta to deal with fixing C pre-declarations, it's almost certainly a bug I've introduced in that.

patflick commented 12 years ago

fixed @hach-que the local stack frame was not adressed correctly, it starts at Y-3, not at Y (see stack frame structure description in bootstram.asm, and hopefully soon in the real docu :) )

kierenj commented 12 years ago

Not looking to jump the gun, but the next Windows binary release that would include this fix, is there an ETA?

hach-que commented 12 years ago

r4d2: Y is intentionally ahead of the return value and previous Y address. This prevents stack smashing (somewhat). Can you fix it so that instead of adjusting the addressing in the produced C code, the bootstrap.asm _stack_caller_init is fixed so that Y is at the correct position?

patflick commented 12 years ago

Currently we have this Stack Layout:

//    Stack Layout:
//
//  ---------------------
// |                     |   
// |  Local Variables    | (initialized via SP = SP-(LocalSize))
// |                     |
//  ---------------------
// |   RETURN ADDRESS    |   <- SP (after init)
//  ---------------------
// |  NEXT STACK FRAME   |   -> points to old Y in higher memory
//  ---------------------
// |                     |   <- Y (after init)
// |   Function Paramter |
// |        Size X       |
//  ---------------------

We could reorder it in this way: Stack Positions are still evaluated with Y MINUS Position

//  ---------------------
// |                     |   
// |  Local Variables    | (initialized via SP = SP-(LocalSize))
// |                     |
//  ---------------------
// |                     |   
// |  Function Paramter  |
// |        Size X       |   <- Y (after init)
//  ---------------------
// |   RETURN ADDRESS    |   <- SP (after init)
//  ---------------------
// |  NEXT STACK FRAME   |   -> points to old Y in higher memory
//  ---------------------

Note: Y should always point at a Position that is a fixed constant from the NEXT STACK FRAME pointer and the RETURN ADDRESS.

In my opinion the first one has an advantage because Y "splits" the function parameters (Y+Position) and the local variables (Y-3-Position), and the addressing is independent of the localSize and paramterSize().

Which one would you choose? Any other ideas?

patflick commented 12 years ago

@hach-que After talking to hachque about our stack layout, i think we agreed on the following, which I will implement in the next few days:

//  ---------------------
// |                     |   
// |  Local Variables    | (initialized via SP = SP-(LocalSize) first thing in callee)
// |                     |   <- Z (shortly after initialization of Stack in callee)
//  ---------------------
// |   RETURN ADDRESS    |   <- SP (after init)
//  ---------------------
// |  NEXT STACK FRAME   |   -> points to old Y in higher memory
//  ---------------------
// |                     |   <- Y (after init)
// |  Function Paramter  |
// |        Size X       |
//  ---------------------
patflick commented 12 years ago

the stack is handled differently now anyway, closing...