PUNTEROS GENÉRICOS
El compilador C51 permite operar con punteros genéricos, y desde la versión 3.00 también con punteros específicos.
Un puntero genérico puede apuntar a cualquier objeto y en cualquier área de memoria. Ocupa 3 bytes: el primero para indicar el tipo de memoria al que apunta (1=idata, 2=xdata, 3=pdata, 4=data, 5=code), y los otros dos para almacenar la dirección del objeto apuntado.
Un puntero específico apunta a objetos residentes en tipos concretos de memoria. Para su almacenamiento requiere: 1 byte (punteros a data, idata, y pdata), o 2 bytes (punteros a xdata y code). Los punteros específicos son muy eficientes y reducen el tamaño de código empleado por el compilador.
Ejemplo, al compilar el siguiente código:
xdata char buffer[10] ; code char message[] = "HELLO" ; void main(void) { char *s ; char *d ; s = message ; d = buffer ; while(*s != '\0') { *d++ = *s++ ; } }
Se obtiene:
RSEG ?XD?T1 buffer: DS 10 RSEG ?CO?T1 message: DB 'H' ,'E' ,'L' ,'L' ,'O' ,000H ; ; ; xdata char buffer[10] ; ; code char message[] = "HELLO" ; ; ; void main(void) { RSEG ?PR?main?T1 USING 0 main: ; ; char *s ; ; char *d ; ; ; s = message ; MOV s?02,#05H MOV s?02+01H,#HIGH message MOV s?02+02H,#LOW message ; d = buffer ; MOV d?02,#02H MOV d?02+01H,#HIGH buffer MOV d?02+02H,#LOW buffer ?C0001: ; ; while(*s != '\0') { MOV R3,s?02 MOV R2,s?02+01H MOV R1,s?02+02H LCALL ?C_CLDPTR JZ ?C0003 ; *d++ = *s++ ; INC s?02+02H MOV A,s?02+02H JNZ ?C0004 INC s?02+01H ?C0004: DEC A MOV R1,A LCALL ?C_CLDPTR MOV R7,A MOV R3,d?02 INC d?02+02H MOV A,d?02+02H MOV R2,d?02+01H JNZ ?C0005 INC d?02+01H ?C0005: DEC A MOV R1,A MOV A,R7 LCALL ?C_CSTPTR ; } SJMP ?C0001 ; } ?C0003: RET ; END OF main END
Como se puede apreciar, los punteros '*s' y '*d' ocupan 3 bytes. El byte '05' de s indica que se trata de un puntero a un objeto en code, mientras que el byte '02' señala que el puntero d apunta a un objeto en xdata. Los bytes que indican el tipo de memoria apuntado son:
CODE - 05 XDATA - 02 PDATA - 03 DATA - 04 IDATA - 01