ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
21 ноября
619595 Топик полностью
Vit (15.09.2015 23:29, просмотров: 605) ответил Олдфаг на А вот у меня давно стоит вопрос: у AVR,даже у взрослых, setjmp не сохраняет RAMPZ. Безопасно ли это?
Не у верен, что не сохраняет Вот такие сорцы находятся ;---------------------------------------------------------------------------- ; ; Library routines for the ATMEL AT90S processors ; setjmp/longjmp ; ; Copyright 1996-1998 IAR Systems. All rights reserved. ; ; $Revision: 1.12 $ ; ;---------------------------------------------------------------------------- #include "macros.m90" PUBLISH MACRO PUBLIC ?\1_0 PUBLIC ?\1_1 PUBLIC ?\1_2 PUBLIC ?\1_3 PUBLIC ?\1_4 PUBLIC ?\1_5 PUBLIC ?\1_6 PUBLIC ?\1_7 PUBLIC ?\1_8 PUBLIC ?\1_9 PUBLIC ?\1_10 PUBLIC ?\1_11 PUBLIC ?\1_12 ENDM ENTRY MACRO \1 0,1,R15 \1 1,2,R14 \1 2,3,R13 \1 3,4,R12 \1 4,5,R11 \1 5,6,R10 \1 6,7,R9 \1 7,8,R8 \1 8,9,R7 \1 9,10,R6 \1 10,11,R5 \1 11,12,R4 \1 12 ENDM REGS MACRO \1 R15 \1 R14 \1 R13 \1 R12 \1 R11 \1 R10 \1 R9 \1 R8 \1 R7 \1 R6 \1 R5 \1 R4 ENDM SAVE MACRO RSEG CODE:CODE:NOROOT PUBLIC ?setjmp_save_\1 ?setjmp_save_\1: ST Z+,\1 ENDM RESTORE MACRO RSEG CODE:CODE:NOROOT PUBLIC ?longjmp_restore_\1 ?longjmp_restore_\1: LD \1,Z+ ENDM ENTRY1 MACRO RSEG CODE:CODE:NOROOT ?setjmp_\1: IF _args > 1 REQUIRE ?setjmp_\2 IF _args > 2 REQUIRE ?setjmp_save_\3 ENDIF ENDIF ENDM ENTRY2 MACRO RSEG CODE:CODE:NOROOT ?longjmp_\1: IF _args > 1 REQUIRE ?longjmp_\2 IF _args > 2 REQUIRE ?longjmp_restore_\3 ENDIF ENDIF ENDM #define SPL 0x3D #define SPH 0x3E #ifdef __XMEGA_CORE__ #define CCP 0x34 #endif /* __XMEGA_CORE__ */ ;------------------------------------------------------------------------- ; ; Function: setjmp ; ; Created: 18/Jun/96 IANP ; ; Inputs: P2:P1:P0 - jmp_buf ; ; Returns: P2:P1:P0 - == 0 when the buffer is set up, ; != 0 when returning from a longjmp ; ; Size: ; ; Destroys: T0 T1 T2 T3 Z (and all other scratch registers ; if returning from a longjmp). ; ; Description: ; Store the stack and register environment in the buffer pointed to ; by P2:P1:P0. PC, SP, Y, and all non-scratch registers are stored. ; ;------------------------------------------------------------------------- MODULE setjmp PUBLISH setjmp ENTRY ENTRY1 MOV Z0,P0 #if (A90_POINTER_REG_SIZE > 1) #if (MEMORY_MODEL == SMALL_MEMORY_MODEL) || (MEMORY_MODEL == LARGE_MEMORY_MODEL) MOV Z1,P1 #else LDI Z1,0 ; Running -v[3,5] -mt #endif #if (A90_POINTER_REG_SIZE == 3) #if (MEMORY_MODEL == SMALL_MEMORY_MODEL) CLR T0 OUT RAMPZ,T0 #else OUT RAMPZ,P2 #endif #endif #endif REQUIRE ?SAVE_R24 REGS SAVE RSEG CODE:CODE:NOROOT ?SAVE_R24: ST Z+,R24 ; save R24 ST Z+,R25 ; save R25 ST Z+,R26 ; save R26 ST Z+,R27 ; save R27 ST Z+,Y0 ; save Y0 ST Z+,Y1 ; save Y1 ;; read PC by popping the return address stack #ifdef A90_LARGE_CODE POP T2 #endif POP T1 POP T0 ST Z+,T0 ; save PC low ST Z+,T1 ; save PC high #ifdef A90_LARGE_CODE ST Z+,T2 ; save PC highest #endif ;; read SP from SFR SP IN T3,SPL ST Z+,T3 ; save SP low #if A90_POINTER_REG_SIZE > 1 IN T3,SPH ST Z+,T3 ; save SP high #endif LDI P0,0 ; return value 0 LDI P1,0 #ifdef __HAS_ENHANCED_CORE__ MOVW Z1:Z0,T1:T0 #else MOV Z0,T0 MOV Z1,T1 #endif #ifdef A90_LARGE_CODE OUT EIND,T2 EIJMP ; return #else IJMP #endif ENDMOD ;------------------------------------------------------------------------- ; ; Function: longjmp ; ; Created: 18/Jun/96 IANP ; ; Inputs: P2:P1:P0 - jmp_buf ; Q1:Q0 - value to give as "return" from setjmp ; ; Returns: (not applicable) ; ; Size: ; ; Destroys: All scratch registers. ; ; Description: ; Restore the stack and register environment from the buffer pointed to ; by P2:P1:P0. PC, SP, Y, and all non-scratch registers are stored. ; ;------------------------------------------------------------------------- MODULE longjmp PUBLISH longjmp #if (A90_POINTER_REG_SIZE == 3) && (MEMORY_MODEL == LARGE_MEMORY_MODEL) #define V0 Q0 #define V1 Q1 #else #define V0 R18 #define V1 R19 #endif ENTRY ENTRY2 MOV Z0,P0 #if A90_POINTER_REG_SIZE > 1 #if (MEMORY_MODEL == SMALL_MEMORY_MODEL) || (MEMORY_MODEL == LARGE_MEMORY_MODEL) MOV Z1,P1 #else CLR Z1 ; Running -v[3,5] -mt #endif #if (A90_POINTER_REG_SIZE == 3) CLR T0 #if (MEMORY_MODEL == SMALL_MEMORY_MODEL) OUT RAMPZ,T0 #else OUT RAMPZ,P2 #endif OUT RAMPD,T0 ; Keep RAMPD zero #endif #endif MOV P0,V0 MOV P1,V1 ; return value OR V0,V1 BRNE ?SKIP LDI P0,1 ; zero return --> make it non-zero ?SKIP: REQUIRE ?RESTORE_R24 REGS RESTORE RSEG CODE:CODE:NOROOT ?RESTORE_R24: LD R24,Z+ ; restore R24 LD R25,Z+ ; restore R25 LD R26,Z+ ; restore R26 LD R27,Z+ ; restore R27 #ifdef __XMEGA_CORE__ LD Q0,Z+ ; restore Y0 LD Q1,Z+ ; restore Y1 MOVW Y1:Y0,Q1:Q0 #else /* Classic */ ;; Disable interrupts while restoring SP and Y IN Q0,SREG CLI ; disable interrupt LD Y0,Z+ ; restore Y0 LD Y1,Z+ ; restore Y1 #endif /* !Classic */ ;; saved PC LD T0,Z+ ; restore PC low LD T1,Z+ ; restore PC high #ifdef A90_LARGE_CODE LD T2,Z+ ; restore PC highest #endif #ifdef __XMEGA_CORE__ LDI Q0,0x9D LD Q1,Z+ ; restore SP low LD Q2,Z+ ; restore SP high OUT CCP,Q0 ;; store saved SP in SFR SP, while interrupts are disabled OUT SPL,Q1 OUT SPH,Q2 #else /* Classic */ ;; store saved SP in SFR SP, while interrupts are disabled LD T3,Z+ ; restore SP low OUT SPL,T3 #if A90_POINTER_REG_SIZE > 1 LD T3,Z+ ; restore SP high OUT SPH,T3 #endif ;; Restore interrupt flag OUT SREG,Q0 #endif /* !Classic */ #ifdef __HAS_ENHANCED_CORE__ MOVW Z1:Z0,T1:T0 #else MOV Z0,T0 MOV Z1,T1 #endif #ifdef A90_LARGE_CODE OUT EIND,T2 EIJMP ; return #else IJMP #endif END ;---------------------------------------------------------------------------- ; $Log: l05.s90 $ ; Revision 1.12 2007/09/17 13:44:18Z IPEO ; Revision 1.11 2003/12/09 11:34:30Z IPEO ; Revision 1.10 2003/10/24 11:45:21Z IPEO ; Revision 1.9 2003/10/10 14:06:42Z IPEO ; S031011110A ; Revision 1.8 2003/10/01 12:19:54Z IPEO ; Revision 1.7 2003/09/03 13:05:10Z IPEO ; Revision 1.6 2003/08/22 14:09:14Z IPEO ; Revision 1.5 2003/08/22 08:54:13Z IPEO ; Revision 1.4 2003/08/20 08:39:01Z IPEO ; Revision 1.3 2003/08/05 15:35:25Z IPEO ; Revision 1.2 2002/11/27 16:45:48Z IPEO ; Revision 1.4 2000/12/07 14:48:17 daniel ; Revision 1.3 2000/10/19 09:17:46 daniel ; Revision 1.2 2000/05/31 14:55:23 daniel ; Revision 1.1 1999/10/18 09:06:31 daniel ; Initial revision
;----------------------------------------------------------------------------
;               			
;		    MACROS.M90					
;
;	This module contains the A90/AVR C macros				
;	used by cstartup.s90 and other assemble source.
;
;   File version:   $Revision: 1.8 $
;								 	
;								 	
;----------------------------------------------------------------------------
#if (((__TID__ >> 8) & 0x7F) != 90)
#error This file should only be assembled by aa90 or aavr
#endif
#define A90_PROC_OPTION		((__TID__ >> 4) & 0x0F)
/* Long or relative jumps and calls */
#if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 1)
#define XCALL	RCALL
#define XJMP	RJMP
#else
#define XCALL	CALL
#define XJMP	JMP
#endif
/* Length of pointer registers (X/Y/Z) */
#if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)
#define A90_POINTER_REG_SIZE	1
#define A90_TINY_INDEX
#else /*!(A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)*/
#if (A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)
#define A90_POINTER_REG_SIZE	2
#else /*!(A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)*/
#if (A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)
#define A90_POINTER_REG_SIZE	3
#define A90_EXTENDED_DATA
#else /*!(A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)*/
#error Unknown processor option!!
#endif /*!(A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)*/
#endif /*!(A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)*/
#endif /*!(A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)*/
#if (A90_PROC_OPTION > 4)
#define A90_LARGE_CODE
#endif
#if (A90_PROC_OPTION > 1)
#define A90_HAS_POSSIBLE_ELPM
#endif
#ifdef A90_HAS_POSSIBLE_ELPM
#ifdef __HAS_ELPM__
#define A90_HAS_ELPM
#else
#ifndef SMALL_FLASH
#define A90_HAS_ELPM
#endif
#endif
#endif
#if A90_PROC_OPTION > 1
#define A90_24BIT_GENERIC
#endif
#if A90_PROC_OPTION < 2
#define A90_16BIT_GENERIC
#endif
#ifdef __MEMORY_MODEL__
#define TINY_MEMORY_MODEL 0
#define SMALL_MEMORY_MODEL 1
#define LARGE_MEMORY_MODEL 2
#define GENERIC_MEMORY_MODEL 3
#define HUGE_MEMORY_MODEL 4
#if __MEMORY_MODEL__ == 1
#undef MEMORY_MODEL
#define MEMORY_MODEL TINY_MEMORY_MODEL
#endif
#if __MEMORY_MODEL__ == 2
#undef MEMORY_MODEL
#define MEMORY_MODEL SMALL_MEMORY_MODEL
#endif
#if __MEMORY_MODEL__ == 3
#undef MEMORY_MODEL
#define MEMORY_MODEL LARGE_MEMORY_MODEL
#endif
#if __MEMORY_MODEL__ == 4
#undef MEMORY_MODEL
#define MEMORY_MODEL GENERIC_MEMORY_MODEL
#endif
#if __MEMORY_MODEL__ == 5
#undef MEMORY_MODEL
#define MEMORY_MODEL HUGE_MEMORY_MODEL
#endif
#else
#ifdef MEMORY_MODEL
#define t 0
#define s 1
#define l 2
#define g 3
#define h 4
#define TINY_MEMORY_MODEL 0
#define SMALL_MEMORY_MODEL 1
#define LARGE_MEMORY_MODEL 2
#define GENERIC_MEMORY_MODEL 3
#define HUGE_MEMORY_MODEL 4
#if MEMORY_MODEL == t
#undef MEMORY_MODEL
#define MEMORY_MODEL TINY_MEMORY_MODEL
#endif
#if MEMORY_MODEL == s
#undef MEMORY_MODEL
#define MEMORY_MODEL SMALL_MEMORY_MODEL
#endif
#if MEMORY_MODEL == l
#undef MEMORY_MODEL
#define MEMORY_MODEL LARGE_MEMORY_MODEL
#endif
#if MEMORY_MODEL == g
#undef MEMORY_MODEL
#define MEMORY_MODEL GENERIC_MEMORY_MODEL
#endif
#if MEMORY_MODEL == h
#undef MEMORY_MODEL
#define MEMORY_MODEL HUGE_MEMORY_MODEL
#endif
#undef t
#undef s
#undef l
#undef g
#undef h
#endif
#endif
/* Register nicknames */
#define T0 R0
#define T1 R1
#define T2 R2
#define T3 R3
#define P0 R16
#define P1 R17
#define P2 R18
#define P3 R19
#define Q0 R20
#define Q1 R21
#define Q2 R22
#define Q3 R23
#define X0 R26
#define X1 R27
#define X2 R25
#define Y0 R28
#define Y1 R29
#define Z0 R30
#define Z1 R31
#define Z2 R19
/* I/O-Space Register nicknames */
#define RAMPD 0x38
#define RAMPX 0x39
#define RAMPY 0x3A
#define RAMPZ 0x3B
#define EIND  0x3C
#define SREG  0x3F