How do I perform a long jump to a numerical address from my C code? I'm pretty sure I have to do this with inline assembly - however that seems complicated for C51. I figured in C I could do this:
typedef void (*jmpPtr)(void); jmpPtr jmp; ... unsigned int address = 0x4000U; jmp = (jmpPtr) address; (*jmp)();
Yes, and I'm using the default optimization level. However, it appears that I should have been more clear and made the distinction between the techniques for the casual reader. The "function pointer as data object" approach that both Ted and Mark are attempting to use results in a call (through a library routine, no less).
00A2 AA00 R MOV R2,lcall 00A4 A900 R MOV R1,lcall+01H 00A6 120000 E LCALL ?C?ICALL
0081 124000 LCALL 04000H
00A9 024000 LJMP 04000H
I think Dan's point is that, if you have the right level of optimization, and you place the subroutine call at the end of the function, the compiler will emit a jmp not a call.
So does this with a lot less parentheses:
void (code *lcall)(void) = 0x4000; lcall();
Having recently done this for a project, I know that the following code produces an LJMP instruction when placed at the end of a function (which it likely would be, given it's application):
#define JMP_TARGET_ADDR ((unsigned char code *)0x4000) /* At end of function here... */ ((void (*)())JMP_TARGET_ADDR)(); }
Just to make it more readable I suppose. I'm not sure I'd agree that 5 lines is more readable than 2. To each their own. Setjmp() and longjmp() save the state from one code point to another and doesn't allow for specifying an address. Good point. If you don't like the LCALL then you'll have to use some assembler I'm afraid. How bad is the LCALL implementation for you? - Mark
First, why all the hoops (eg typedef)? Just to make it more readable I suppose. Setjmp() and longjmp() save the state from one code point to another and doesn't allow for specifying an address. The reason I need an address is because I am going to dynamically program Flash and then execute code out of the just-programmed Flash.
First, why all the hoops (eg typedef)?
Just: void (code *jump)(void) = 0x4000; and: jump();
View all questions in Keil forum