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.