Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compiler optimizes out pointer to function when address is assigned manually

I need to call a function at address 0xDD2:

// foo.h
void foo(void) __at(0xDD2);

// foo.c
#include "foo.h"
void foo(void)
{
    // some code
}

This code works:

#include "foo.h"
void main(void)
{
    void (*a)(void) = &foo;
    a();
}

However, this one doesn't:

#include "foo.h"
void main(void)
{
    void (*a)(void) = (void (*)(void))(0x0DD2);
    a();
}

The compiler (XC8) says: main.c:5:: warning: (759) expression generates no code and debugger passes these lines while debugging.

I need second one (call function just by its address). Why compiler optimizes it out? Is there any mistake in pointer assignment? Changing optimization level of compiler didn't help.

like image 232
AmirSina Mashayekh Avatar asked Jun 09 '20 11:06

AmirSina Mashayekh


1 Answers

This seems to do what you asked for:

/*
 * File:   main.c
 * Author: dan1138
 * Target: PIC18F47Q10
 * Compiler: XC8 v2.20
 * 
 * See: https://stackoverflow.com/questions/62282036/compiler-optimizes-out-pointer-to-function-when-address-is-assigned-manually/62297967#62297967
 *
 * Created on June 9, 2020, 11:42 PM
 */
#pragma config FEXTOSC = OFF, RSTOSC = HFINTOSC_64MHZ, CLKOUTEN = OFF
#pragma config CSWEN = ON, FCMEN = OFF, MCLRE = EXTMCLR, PWRTE = OFF
#pragma config LPBOREN = OFF, BOREN = SBORDIS, BORV = VBOR_190
#pragma config ZCD = OFF, PPS1WAY = OFF, STVREN = ON, XINST = OFF
#pragma config WDTCPS = WDTCPS_31, WDTE = OFF, WDTCWS = WDTCWS_7, WDTCCS = SC
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRT4 = OFF, WRT5 = OFF, WRT6 = OFF, WRT7 = OFF
#pragma config WRTC = OFF, WRTB = OFF, WRTD = OFF
#pragma config SCANE = ON, LVP = OFF, CP = OFF, CPD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
#pragma config EBTR4 = OFF, EBTR5 = OFF, EBTR6 = OFF, EBTR7 = OFF
#pragma config EBTRB = OFF

#include <xc.h>

void main(void)
{
    extern void foo(void) __at(0xDD2);
    void (* volatile a)(void) = foo;

    a();
}    

Disassembly:

!void main(void)
!{
!    extern void foo(void) __at(0xDD2);
!    void (* volatile a)(void) = foo;
0x1FFD4: MOVLW 0xD2
0x1FFD6: MOVWF __pcstackCOMRAM, ACCESS
0x1FFD8: MOVLW 0xD
0x1FFDA: MOVWF 0x2, ACCESS
0x1FFDC: MOVLW 0x0
0x1FFDE: MOVWF 0x3, ACCESS
!    a();
0x1FFE0: RCALL 0xFFE6
0x1FFE2: GOTO 0x1FFFA
0x1FFE4: NOP
0x1FFE6: PUSH
0x1FFE8: MOVWF PCLATH, ACCESS
0x1FFEA: MOVF __pcstackCOMRAM, W, ACCESS
0x1FFEC: MOVWF TOS, ACCESS
0x1FFEE: MOVF 0x2, W, ACCESS
0x1FFF0: MOVWF TOSH, ACCESS
0x1FFF2: MOVF 0x3, W, ACCESS
0x1FFF4: MOVWF TOSU, ACCESS
0x1FFF6: MOVF PCLATH, W, ACCESS
0x1FFF8: RETURN 0
!}
0x1FFFA: BSF _ccovbit2_1, 0, ACCESS
0x1FFFC: GOTO 0x0
0x1FFFE: NOP
like image 129
Dan1138 Avatar answered Oct 26 '22 01:10

Dan1138