#329 pops with no pushs

closed-fixed
5
2013-05-25
2002-04-21
Anonymous
No

Hello!

SDCC V2.3.0, using Borland binaries, produces code with
lots of pops but with no corresponding pushs. The
program will crash, because of the non symmetrical
usage of push (or lcall) and pop (or ret).

The appended files (ZIP with SRC.C and SRC.ASM)
demonstrate the issue.

An ISR calls the function subroutine().
The function then calls another function my_func()
indirectly via a simple table (struct, array)
containing the address of my_func(). When my_func()
returns back to subroutine(), the code at label 00103$
will be executed. There you will find
pop psw
pop (0+1)
pop (0+0)
pop (0+7)
pop (0+6)
pop (0+5)
pop (0+4)
pop (0+3)
pop (0+2)
but you will not find any corresponding pushs before
(or after). All relevant functions, ISR, subroutine()
and my_func() were declared using register bank 2. No
specific options other than -I and -L were used.

How can this problem be solved?
Is there any workaround?

Greetings,
Patrick Gehriger

Discussion

  • Bernhard Held

    Bernhard Held - 2002-04-22

    Logged In: YES
    user_id=203539

    There are no appended files (SF seems to be buggy).
    Patrick, could you please try again?

     
  • Nobody/Anonymous

    Logged In: NO

    I try again to attach the file(s) using netscape 2.02 on
    OS/2 instead of IE5.x on Win98. I hope this time it
    works...

    Greetings,
    Patrick Gehriger

     
  • Nobody/Anonymous

    Logged In: NO

    Hello Mr. Held.
    As the mechanism for file attachments seems not to work, I
    include SRC.C and SRC.ASM here.

    Greetings,
    Patrick Gehriger

    C:
    #include <at89x51.h> // SDCC

    void UART_init(void)
    {
    // Timer_1 (Used for UART-BaudRate-Generation):
    TI= 0; // Reset transmit flag.
    RI= 0; // Reset receive flag.
    TMOD&= 0x0F; // Clear all T1-Bits.
    TMOD|= 0x20; // Mode 2 (8-Bit Auto Reload).
    TH1= 204u; // Reload-Value for fosc=24MHz,
    1200baud.
    TR1= 1; // Run Timer.

    // UART:
    PCON&= 0x7F; // SMOD=0 (BaudRate*1=0, BaudRate*2=1).
    SCON&= 0x1F; // Clear all SM-Bits (Serial Port
    Mode).
    SCON|= 0x60; // Mode 1 (8-Bit UART, BaudRate
    variable), Valid Stop-Bit checked (Bit5=1).
    REN= 1; // Enable-RXD (Reception) (Disable=0,
    Enable=1).

    return;
    }

    void init(void)
    {
    // Devices:
    UART_init();

    // Interrupt Priority (Lo=0, Hi=1):
    PX0= 0; // External-INT0-Interrupt
    PT0= 0; // Timer-0-Interrupt
    PX1= 0; // External-INT1-Interrupt
    PT1= 0; // Timer-1-Interrupt
    PS= 0; // UART-Interrupt
    // PT2= 0; // Timer-2-Interrupt (x52 only!)

    // Local Interrupt Enables:
    EX0= 0; // External-INT0-Interrupt
    ET0= 0; // Timer-0-Interrupt
    EX1= 0; // External-INT1-Interrupt
    ET1= 0; // Timer-1-Interrupt
    ES= 1; // UART-Interrupt
    // ET2= 0; // Timer-2-Interrupt (x52 only!)

    // External INT0:
    IT0= 1; // Type (Level=0, Edge=1)

    // External INT1:
    IT1= 1; // Type (Level=0, Edge=1)

    // Global Interrupt Enable:
    EA= 1;

    return;
    }

    #pragma SAVE
    #pragma NOOVERLAY
    void my_func(void) using 2
    {
    // Some C code.

    return;
    }
    #pragma RESTORE

    struct command_tab_struct
    {
    char id; // Identifier (tag, code).
    unsigned char clength; // Command data length.
    unsigned char rlength; // Reply data length.
    void (*func)(void); // Function address.
    };

    const struct command_tab_struct com_slv_command_tab[]=
    {
    // MY_FUNC
    {
    ' ', // Identifier (tag, code).
    000, // Command data length.
    000, // Reply data length.
    my_func // Execution function.
    }
    };

    void subroutine(void) using 2
    {
    // Call function my_func():
    (*com_slv_command_tab[0].func)();

    return;
    }

    #pragma SAVE
    #pragma NOOVERLAY
    void UART_int_func(void) interrupt 4 using 2
    {
    // Ignore transmit interrupt, just process receive
    interrupt:

    TI= 0; // Reset send flag.

    if (RI) // If new char received..
    {
    RI= 0; // Reset receive flag.

    // Call function my_func() indirectly in
    subroutine():
    subroutine();
    }

    return;
    }
    #pragma RESTORE

    void main(void)
    {
    _asm
    mov sp,#__start__stack
    _endasm;

    init();

    while (1);
    }

    ASM:

    ;--------------------------------------------------------
    ; File Created by SDCC : FreeWare ANSI-C Compiler
    ; Version 2.3.0 Sun Apr 21 17:53:35 2002

    ;--------------------------------------------------------
    .module src

    ;--------------------------------------------------------
    ; Public variables in this module
    ;--------------------------------------------------------
    .globl _com_slv_command_tab
    .globl _main
    .globl _UART_int_func
    .globl _subroutine
    .globl _my_func
    .globl _init
    .globl _UART_init
    ;--------------------------------------------------------
    ; special function registers
    ;--------------------------------------------------------
    _P0 = 0x0080
    _SP = 0x0081
    _DPL = 0x0082
    _DPH = 0x0083
    _PCON = 0x0087
    _TCON = 0x0088
    _TMOD = 0x0089
    _TL0 = 0x008a
    _TL1 = 0x008b
    _TH0 = 0x008c
    _TH1 = 0x008d
    _P1 = 0x0090
    _SCON = 0x0098
    _SBUF = 0x0099
    _P2 = 0x00a0
    _IE = 0x00a8
    _P3 = 0x00b0
    _IP = 0x00b8
    _PSW = 0x00d0
    _ACC = 0x00e0
    _A = 0x00e0
    _B = 0x00f0
    ;--------------------------------------------------------
    ; special function bits
    ;--------------------------------------------------------
    _P0_0 = 0x0080
    _P0_1 = 0x0081
    _P0_2 = 0x0082
    _P0_3 = 0x0083
    _P0_4 = 0x0084
    _P0_5 = 0x0085
    _P0_6 = 0x0086
    _P0_7 = 0x0087
    _IT0 = 0x0088
    _IE0 = 0x0089
    _IT1 = 0x008a
    _IE1 = 0x008b
    _TR0 = 0x008c
    _TF0 = 0x008d
    _TR1 = 0x008e
    _TF1 = 0x008f
    _P1_0 = 0x0090
    _P1_1 = 0x0091
    _P1_2 = 0x0092
    _P1_3 = 0x0093
    _P1_4 = 0x0094
    _P1_5 = 0x0095
    _P1_6 = 0x0096
    _P1_7 = 0x0097
    _RI = 0x0098
    _TI = 0x0099
    _RB8 = 0x009a
    _TB8 = 0x009b
    _REN = 0x009c
    _SM2 = 0x009d
    _SM1 = 0x009e
    _SM0 = 0x009f
    _P2_0 = 0x00a0
    _P2_1 = 0x00a1
    _P2_2 = 0x00a2
    _P2_3 = 0x00a3
    _P2_4 = 0x00a4
    _P2_5 = 0x00a5
    _P2_6 = 0x00a6
    _P2_7 = 0x00a7
    _EX0 = 0x00a8
    _ET0 = 0x00a9
    _EX1 = 0x00aa
    _ET1 = 0x00ab
    _ES = 0x00ac
    _EA = 0x00af
    _P3_0 = 0x00b0
    _P3_1 = 0x00b1
    _P3_2 = 0x00b2
    _P3_3 = 0x00b3
    _P3_4 = 0x00b4
    _P3_5 = 0x00b5
    _P3_6 = 0x00b6
    _P3_7 = 0x00b7
    _RXD = 0x00b0
    _TXD = 0x00b1
    _INT0 = 0x00b2
    _INT1 = 0x00b3
    _T0 = 0x00b4
    _T1 = 0x00b5
    _WR = 0x00b6
    _RD = 0x00b7
    _PX0 = 0x00b8
    _PT0 = 0x00b9
    _PX1 = 0x00ba
    _PT1 = 0x00bb
    _PS = 0x00bc
    _P = 0x00d0
    _FL = 0x00d1
    _OV = 0x00d2
    _RS0 = 0x00d3
    _RS1 = 0x00d4
    _F0 = 0x00d5
    _AC = 0x00d6
    _CY = 0x00d7
    ;--------------------------------------------------------
    ; internal ram data
    ;--------------------------------------------------------
    .area DSEG (DATA)
    ;--------------------------------------------------------
    ; overlayable items in internal ram
    ;--------------------------------------------------------
    .area OSEG (OVR,DATA)
    ;--------------------------------------------------------
    ; Stack segment in internal ram
    ;--------------------------------------------------------
    .area SSEG (DATA)
    __start__stack:
    .ds 1

    ;--------------------------------------------------------
    ; indirectly addressable internal ram data
    ;--------------------------------------------------------
    .area ISEG (DATA)
    ;--------------------------------------------------------
    ; bit data
    ;--------------------------------------------------------
    .area BSEG (BIT)
    ;--------------------------------------------------------
    ; external ram data
    ;--------------------------------------------------------
    .area XSEG (XDATA)
    ;--------------------------------------------------------
    ; interrupt vector
    ;--------------------------------------------------------
    .area CSEG (CODE)
    __interrupt_vect:
    ljmp __sdcc_gsinit_startup
    reti
    .ds 7
    reti
    .ds 7
    reti
    .ds 7
    reti
    .ds 7
    ljmp _UART_int_func
    .ds 5
    reti
    .ds 7
    ;--------------------------------------------------------
    ; global & static initialisations
    ;--------------------------------------------------------
    .area GSINIT (CODE)
    .area GSFINAL (CODE)
    .area GSINIT (CODE)
    __sdcc_gsinit_startup:
    mov sp,#23
    lcall __sdcc_external_startup
    mov a,dpl
    jz __sdcc_init_data
    ljmp __sdcc_program_startup
    __sdcc_init_data:
    .area GSFINAL (CODE)
    ljmp __sdcc_program_startup
    ;--------------------------------------------------------
    ; Home
    ;--------------------------------------------------------
    .area HOME (CODE)
    .area CSEG (CODE)
    ;--------------------------------------------------------
    ; code
    ;--------------------------------------------------------
    .area CSEG (CODE)
    __sdcc_program_startup:
    lcall _main
    ; return from main will lock up
    sjmp .
    ;-----------------------------------------------------------
    -
    ;Allocation info for local variables in function 'UART_init'
    ;-----------------------------------------------------------
    -
    ; src.c 3
    ; -----------------------------------------
    ; function UART_init
    ; -----------------------------------------
    _UART_init:
    ar2 = 0x02
    ar3 = 0x03
    ar4 = 0x04
    ar5 = 0x05
    ar6 = 0x06
    ar7 = 0x07
    ar0 = 0x00
    ar1 = 0x01
    ; src.c 6
    clr _TI
    ; src.c 7
    clr _RI
    ; src.c 8
    anl _TMOD,#0x0F
    ; src.c 9
    orl _TMOD,#0x20
    ; src.c 10
    mov _TH1,#0xCC
    ; src.c 11
    setb _TR1
    ; src.c 14
    anl _PCON,#0x7F
    ; src.c 15
    anl _SCON,#0x1F
    ; src.c 16
    orl _SCON,#0x60
    ; src.c 17
    setb _REN
    ; src.c 19
    00101$:
    ret
    ;-----------------------------------------------------------
    -
    ;Allocation info for local variables in function 'init'
    ;-----------------------------------------------------------
    -
    ; src.c 23
    ; -----------------------------------------
    ; function init
    ; -----------------------------------------
    _init:
    ; src.c 26
    lcall _UART_init
    ; src.c 29
    clr _PX0
    ; src.c 30
    clr _PT0
    ; src.c 31
    clr _PX1
    ; src.c 32
    clr _PT1
    ; src.c 33
    clr _PS
    ; src.c 37
    clr _EX0
    ; src.c 38
    clr _ET0
    ; src.c 39
    clr _EX1
    ; src.c 40
    clr _ET1
    ; src.c 41
    setb _ES
    ; src.c 45
    setb _IT0
    ; src.c 48
    setb _IT1
    ; src.c 51
    setb _EA
    ; src.c 53
    00101$:
    ret
    ;-----------------------------------------------------------
    -
    ;Allocation info for local variables in function 'my_func'
    ;-----------------------------------------------------------
    -
    ; src.c 59
    ; -----------------------------------------
    ; function my_func
    ; -----------------------------------------
    _my_func:
    ar2 = 0x12
    ar3 = 0x13
    ar4 = 0x14
    ar5 = 0x15
    ar6 = 0x16
    ar7 = 0x17
    ar0 = 0x10
    ar1 = 0x11
    push psw
    mov psw,#0x10
    ; src.c 63
    00101$:
    pop psw
    ret
    ;-----------------------------------------------------------
    -
    ;Allocation info for local variables in
    function 'subroutine'
    ;-----------------------------------------------------------
    -
    ; src.c 88
    ; -----------------------------------------
    ; function subroutine
    ; -----------------------------------------
    _subroutine:
    push psw
    mov psw,#0x10
    ; src.c 91
    mov dptr,#(_com_slv_command_tab + 0x0003)
    clr a
    movc a,@a+dptr
    mov r2,a
    inc dptr
    clr a
    movc a,@a+dptr
    mov r3,a
    mov a,#00103$
    push acc
    mov a,#(00103$ >> 8)
    push acc
    push ar2
    push ar3
    ret
    00103$:
    pop psw
    pop (0+1)
    pop (0+0)
    pop (0+7)
    pop (0+6)
    pop (0+5)
    pop (0+4)
    pop (0+3)
    pop (0+2)
    ; src.c 93
    00101$:
    pop psw
    ret
    ;-----------------------------------------------------------
    -
    ;Allocation info for local variables in
    function 'UART_int_func'
    ;-----------------------------------------------------------
    -
    ; src.c 98
    ; -----------------------------------------
    ; function UART_int_func
    ; -----------------------------------------
    _UART_int_func:
    push acc
    push b
    push dpl
    push dph
    push psw
    mov psw,#0x10
    ; src.c 102
    clr _TI
    ; src.c 104
    ; Peephole 111 removed ljmp by inverse jump logic
    jnb _RI,00102$
    00106$:
    ; src.c 106
    clr _RI
    ; src.c 109
    lcall _subroutine
    00102$:
    ; src.c 112
    00103$:
    pop psw
    pop dph
    pop dpl
    pop b
    pop acc
    reti
    ;-----------------------------------------------------------
    -
    ;Allocation info for local variables in function 'main'
    ;-----------------------------------------------------------
    -
    ; src.c 117
    ; -----------------------------------------
    ; function main
    ; -----------------------------------------
    _main:
    ar2 = 0x02
    ar3 = 0x03
    ar4 = 0x04
    ar5 = 0x05
    ar6 = 0x06
    ar7 = 0x07
    ar0 = 0x00
    ar1 = 0x01
    ; src.c 125
    mov sp,#__start__stack
    ; src.c 127
    lcall _init
    ; src.c 129
    00102$:
    ; Peephole 132 changed ljmp to sjmp
    sjmp 00102$
    00104$:
    ret
    .area CSEG (CODE)
    _com_slv_command_tab:
    .db #0x20
    .db #0x00
    .db #0x00
    .byte _my_func,(_my_func >> 8)

     
  • Bernhard Held

    Bernhard Held - 2002-04-26

    Logged In: YES
    user_id=203539

    Not reproduceable with 2.3.2.

     
  • Bernhard Held

    Bernhard Held - 2002-04-26
    • milestone: --> fixed
    • assigned_to: nobody --> bernhardheld
    • status: open --> closed-fixed
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks