C251 User's Guide

Memory Model

The most significant impact on code size and execution speed is the memory model. Compiling with the small model always generates the smallest, fastest code possible.

The TINY directive instructs the C251 compiler to use the TINY memory model. In the TINY model, variables, unless declared otherwise, reside in the data memory of the 251. Pointers are near * by default.

If your application has huge data requirements the XTINY memory model is preferred over the XSMALL memory model. The following example shows the influence of the memory models:

char *p;

void test (unsigned int i)  {
  p[i] = 0;
}

This example is compiled in each of the TINY, XSMALL and LARGE models to demonstrate the difference in generated code.

The TINY model translation:

  stmt  level    source

    1          #pragma tiny
    2
    3          char *p;
    4
    5          void test (unsigned int i)  {
    6   1        p[i] = 0;
    7   1      }

;       FUNCTION test (BEGIN)
                                             ; SOURCE LINE # 5
;---- Variable 'i' assigned to Register 'WR6' ----
                                             ; SOURCE LINE # 6
000000 E4             CLR      A             ; A=R11
000001 2E3500      R  ADD      WR6,p
000004 7A39B0         MOV      @WR6,R11      ; A=R11
                                             ; SOURCE LINE # 7
000007 22             RET
;       FUNCTION test (END)

Total Code Size = 8 Bytes

In the TINY model, the variable p is located in the data memory, the default pointer size is 2 bytes, and each of these instructions executes very quickly.

The same code compiled using the XSMALL model:

  stmt  level    source

    1          #pragma xsmall
    2
    3          char *p;
    4
    5          void test (unsigned int i)  {
    6   1        p[i] = 0;
    7   1      }

;       FUNCTION test (BEGIN)
                                             ; SOURCE LINE # 5
000000 7D13           MOV      WR2,WR6
;---- Variable 'i' assigned to Register 'WR2' ----
                                             ; SOURCE LINE # 6
000002 E4             CLR      A             ; A=R11
000003 7E1F0000    R  MOV      DR4,p
000007 2D31           ADD      WR6,WR2
000009 7A1BB0         MOV      @DR4,R11      ; A=R11
                                             ; SOURCE LINE # 7
00000C 22             RET
;       FUNCTION test (END)

Total Code Size = 13 Bytes

In the XSMALL model, the variable p is located in the near memory, the default pointer size is 4 bytes, and the generated code requires more MCU registers and is bigger compared to the TINY model.

The same code compiled using the LARGE model:

  stmt  level    source

    1          #pragma large
    2
    3          char *p;
    4
    5          void test (unsigned int i)  {
    6   1        p[i] = 0;
    7   1      }

;       FUNCTION test (BEGIN)
                                             ; SOURCE LINE # 5
000000 7D13           MOV      WR2,WR6
;---- Variable 'i' assigned to Register 'WR2' ----
                                             ; SOURCE LINE # 6
000002 E4             CLR      A             ; A=R11
000003 900000      R  MOV      DPTR,#WORD0 p
000006 693E0002       MOV      WR6,@DR56+2   ; WORD0(DR56)=DPTR
00000A 0BEA20         MOV      WR4,@DR56     ; WORD0(DR56)=DPTR
00000D 2D31           ADD      WR6,WR2
00000F 7A1BB0         MOV      @DR4,R11      ; A=R11
                                             ; SOURCE LINE # 7
000012 22             RET
;       FUNCTION test (END)

Total Code Size = 19 Bytes

In the LARGE model, the variable p is located in the xdata memory which generates inefficient memory accesses. For big applications you should really use the XSMALL model instead of the LARGE.