9
kiki
353d

C/ASM people, can you explain it?

Comments
  • 17
    Looks like making a void pointer to the address 0, ie setting the instruction pointer to the beginning. Sounds weird but makes sense for a microcontroller
  • 10
    it seems like it's casting a zero into a function pointer and executing it, effectively rerunning everything. I'm not sure if the stack keeps the zero tho, but i would assume yes, because at the end it's kinda just running "the whole firmware" inside a stack frame
  • 6
    Yeah, it's more readable when you format it better:

    ( void (*) (void) )0();

    "void (*) (void)"

    this part says, it's a function pointer to a function that returns void and accepts void, effectively a pointer to a parameterless function with no return

    "0"

    this part is just a zero, which also is the address 0x000..., so that's the point in memory where the pointer is pointing to, effectively the very beginning of the entire program

    "()"

    normal function execution without parameters

    So it's a pointer + execution to a parameterless function at the start of the program. Probably something like a void main() function in the firmware memory at address 0x0000.
  • 2
    if (cmd[1] == RESET) __asm__ ( "CALL 0000");

    Since the firmware starts at 0000, it's similar to JMP 0000. I guess the processor takes care of SP then?
  • 1
    Is that really a good way to do a reset on a microcontroller?
    I mean dont they have reset pins you could use instead
  • 5
    @LotsOfCaffeine with microcontrollers the lines sometimes blur between good/bad practice. This is perfectly valid
  • 2
    @Ranchonyx Has the same vibes as this.
  • 2
    @LotsOfCaffeine Not all of them do, and the ones that do, you might not be able to trigger the reset pin from the inside.
  • 0
    Is there a way to do this that doesn't rely on weird implicit behavior to reset the stack pointer?
  • 0
    @Ranchonyx I'm always doubtful about statements like this. Webdevs also often say that "it looks weird but it's perfectly valid". Every single example of such behavior I'd seen so far had an equivalent solution that said exactly what it did.

    On the rare occasion that weird and confusing solutions really are the only way to do the thing, they can always be broken out into an isolated function or macro and commented properly.
  • 1
    Same thing with using bit shifts to represent log2 operations when the number is never used as a bitfield. If there's a device that does and says exactly what has to be done, why break an abstraction?
Add Comment