Keep variables that are only used in asssembly.

HiTech had a great compiler for PSoC's M8C processor, but, then they were bought by Microchip. Subsequently the HiTech forums were taken off line. At the request of PSoCDeveloper members PSoCDeveloper has created this forum to allow HiTech users to support each other.

Moderator: ericb

Keep variables that are only used in asssembly.

Postby baxsie » Thu Jun 04, 2009 3:42 pm

I have been fighting with another bit of assembly. I had a routine in ImageCraft as its own ASM file. But things get complicated with the parameters passed in A and X, and no stack pointer to create local variables.

So I decided to make a "mainly inline assembly" C routine.

The trouble is that the C compiler would optimize out the locals, and the linker would choke with:

!E \Temp\s7gk.(10432):(800) undefined symbol "dow_crc@old_crc_local"

for the locals where they show up in the assembly.

After much screwing around, I came up with the idea of putting a RET in the assembly, and then using C below the assembly RET to access the variables, like this:
Code: Select all
ubyte dow_crc(ubyte input,ubyte old_crc)
  {
  //input:   A
  //old_crc: X
  ubyte
    count;
  ubyte
    input_local;
  ubyte
    old_crc_local;

  asm("MOV    [dow_crc@input_local],A");
  asm("MOV    [dow_crc@old_crc_local],X");
  asm("MOV    [dow_crc@count],8");
asm("Next_Bit:");
  asm("MOV    A,[dow_crc@input_local]");
  asm("XOR    A,[dow_crc@old_crc_local]");
  asm("RRC    A");
  asm("JNC    Bit_Is_Zero");
  asm("XOR    [dow_crc@old_crc_local],018h");
asm("Bit_Is_Zero:");
  asm("RRC    [dow_crc@old_crc_local]");
  asm("RRC    [dow_crc@input_local]");
  asm("DEC    [dow_crc@count]");
  asm("JNZ    Next_Bit");
  // return(old_crc_local);
  asm("MOV    A,[dow_crc@old_crc_local]");
  asm("ret");
  //This code just convince the compiler to keep variables. And the compiler optimizes it away! (sigh)
  input_local=1;
  count=1;
  old_crc_local=1;
  return(input_local+count+old_crc_local);
  }

Here is where the compiler+linker really surprised me. The C code past the RET does nothing useful, so the compiler or linker completely optimizes it out!
Code: Select all
  7207                          ; *************** function _dow_crc *****************
  7208                          ; Defined at:
  7209                          ;      line 216 in file "./dow.c"
  7210                          ; Parameters:
  7211                          ;      input          reg:    a   type: unsigned char
  7212                          ;      old_crc        reg:    x   type: unsigned char
  7213                          ; Auto variables:
  7214                          ;      count                    type: unsigned char
  7215                          ;      input_local              type: unsigned char
  7216                          ;      old_crc_loca             type: unsigned char
  7217                          ; Return value:
  7218                          ;      type: unsigned char
  7219                          ;      size: 1
  7220                          ; Registers used:
  7221                          ;      a, x, CUR_PP
  7222                          ; Tracked objects:
  7223                          ;      On entry : CUR_PP? IDX_PP? XIO=0 PG? MVR_PP? MVW_PP?
  7224                          ;      On exit  : CUR_PP? IDX_PP? XIO=0 PG=0 MVR_PP? MVW_PP?
  7225                          ;      Unchanged: CUR_PP IDX_PP MVR_PP MVW_PP
  7226                          ; Data sizes:
  7227                          ;      Autos:    3
  7228                          ;      Params:   0
  7229                          ;      Temp:     0
  7230                          ;      Total:    3
  7231                          ; This function calls:
  7232                          ;      Nothing
  7233                          ; This function is called by:
  7234                          ;      _process_packet
  7235                          ;      _DOW_Next
  7236                          ;      _Read_Specific_Temperature
  7237                          ; This function uses a non-reentrant model
  7238                          ;
  7239  001C                    __size_of_dow_crc   equ   __end_of_dow_crc-_dow_crc
  7240                          ;dow.c: 215: ubyte dow_crc(ubyte input,ubyte old_crc)
  7241                          ;dow.c: 216: {
  7242                          ;         XIO=0 PG=0
  7243  36B5                    _dow_crc:
  7244  36B5  53 C3                mov   [??_dow_crc+1], a   ;#
  7245  36B7  5A C2                mov   [??_dow_crc], x   ;#
  7246  36B9  55 C4  08            mov   [??_dow_crc+2], 8   ;#
  7247  36BC                    Next_Bit:   ;#
  7248  36BC  51 C3                mov   a, [??_dow_crc+1]   ;#
  7249  36BE  32 C2                xor   a, [??_dow_crc]   ;#
  7250  36C0  6D                   rrc   a   ;#
  7251  36C1  D004                 jnc   Bit_Is_Zero   ;#
  7252  36C3  36 C2  18            xor   [??_dow_crc], 0x18   ;#
  7253  36C6                    Bit_Is_Zero:   ;#
  7254  36C6  6E C2                rrc   [??_dow_crc]   ;#
  7255  36C8  6E C3                rrc   [??_dow_crc+1]   ;#
  7256  36CA  7A C4                dec   [??_dow_crc+2]   ;#
  7257  36CC  BFEF                 jnz   Next_Bit   ;#
  7258  36CE  51 C2                mov   a, [??_dow_crc]   ;#
  7259  36D0  7F                   ret   ;#
  7260                          ;dow.c: 219: ubyte
  7261                          ;dow.c: 220: count;
  7262                          ;dow.c: 221: ubyte
  7263                          ;dow.c: 222: input_local;
  7264                          ;dow.c: 223: ubyte
  7265                          ;dow.c: 224: old_crc_local;
  7266                          ;dow.c: 226: asm("MOV    [dow_crc@input_local],A");
  7267                          ;dow.c: 227: asm("MOV    [dow_crc@old_crc_local],X");
  7268                          ;dow.c: 228: asm("MOV    [dow_crc@count],8");
  7269                          ;dow.c: 229: asm("Next_Bit:");
  7270                          ;dow.c: 230: asm("MOV    A,[dow_crc@input_local]");
  7271                          ;dow.c: 231: asm("XOR    A,[dow_crc@old_crc_local]");
  7272                          ;dow.c: 232: asm("RRC    A");
  7273                          ;dow.c: 233: asm("JNC    Bit_Is_Zero");
  7274                          ;dow.c: 234: asm("XOR    [dow_crc@old_crc_local],018h");
  7275                          ;dow.c: 245: count=1;
  7276                          ;dow.c: 246: old_crc_local=1;
  7277                          ;dow.c: 247: return(input_local+count+old_crc_local);
  7278                          ;dow.c: 248: }
  7279                          ;         XIO=0 PG=0
  7280  36D1                    __end_of_dow_crc:
  7281                          ; =============== function _dow_crc ends ============

Well, that sofa king weird, but since there will be no compiler upgrades, it should work forever ;)
I'm not getting older. I'm getting bitter.
baxsie
The Big Cheese
The Big Cheese
 
Posts: 420
Joined: Mon Dec 22, 2003 10:08 pm

Return to “%s” HiTech C User-to-User Support

Who is online

Users browsing this forum: No registered users and 1 guest