flashburn
flashburn

Reputation: 4508

Why does this execute a jump instruction?

I have just seen a very interesting C code in the boot loader of a small embedded product.

The code consists of two parts: boot loader and the main code. The start of the main code address is stored in a function pointer. Below is the code I'm talking about

typedef struct {
  uint32_t myOtherField;
  void (*mainCodeStartAddress)(void);
} MyStruct;

MyStruct myStruct = {0x89ABCDEF, 0x12345678};

void main(void) {
  // Some code
  ...
  myStruct.mainCodeStartAddress(); // Jump to the start of the application
}

I can't figure out why this works? Why does a machine go to the application code? Any help is appreciated.

Upvotes: 0

Views: 83

Answers (2)

Clifford
Clifford

Reputation: 93476

If the application code is built with a start address of 0x12345678 (an unlikely address that I assume you have made up for illustration?), then the bootloader need only jump to that start address to start the application. This can be achieved in C code by setting a function-pointer specifically to that address to that a priori known start address value and issuing a call via that function-pointer. A pointer of any kind is merely a memory address, a function pointer is the address of some code, and a call to a void function is simple a call to some address.

Whether this is implemented by a jump, call, or branch instruction is architecture and instruction set dependent; but that does not matter in this case. Neither does it matter that the start address is not a "function" as such, since this function will never return - the separately compiled and linked application code will run it's own C runtime start-up and establish a new stack and static initialisation, destroying the runtime environment of the bootloader. All that is required is that the processor's program-counter is set to the specific address, and that is achieved by calling the function via a pointer. It could equally be achieved for example by:

typedef void(*tStartAddress)(void);
((tStartAddress)(0x12345678)() ; // Set PC to start address

Upvotes: 1

harald
harald

Reputation: 6126

The construct void (*mainCodeStartAddress)(void) declares a function pointer named mainCodeStartAddress. It will point to a function taking no arguments and that doesn't return anything.

You can assign any function of the same type to a function pointer, for example:

void some_function(void)
{
    // Do something useful
}

mystruct.mainCodeStartAddress = some_function;

Then you can call it like this:

mystruct.mainCodeStartAddress();  // Same as calling some_function();

In your example a fixed address is assigned to the function pointer, so when you call the function it points to it jumps to that address and executes it.

Upvotes: 6

Related Questions