Не у верен, что не сохраняет Вот такие сорцы находятся
;----------------------------------------------------------------------------
;
;  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
)