📄 ts_hdr.asm
字号:
/************************************************************************
*
* ts_hdr.asm : $Revision: 1.14 $
*
* (c) Copyright 1996-2002 Analog Devices, Inc. All rights reserved.
*
************************************************************************/
// Used to initialise the base and length registers
.section data1;
.align 4;
.var ___allzeros[4] = 0x00000000, 0x00000000, 0x00000000, 0x00000000;
.var ___allones[4] = 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff;
.section program; // PROG
.global _____system_start;
_____system_start:
// The stack pointers point to the first free quad-word. In addition,
// each stack must have another 4 words for storing linkage info, and
// the J stack has 4 more words for copying the 4 argument registers.
J27 = J31 + (ldf_jstack_base - 12); NOP; NOP;;
K27 = K31 + (ldf_kstack_base - 8);;
// Initialise the circular buffer base and length registers.
#if defined (__WORKAROUND_ANOMALY_0223)
// Can not load to J/K base and Length registers from external memory.
jb0 = 0;;
jb1 = 0;;
jb3:2 = jb1:0;;
jl3:0 = jb3:0;;
kb3:0 = jb3:0;;
kl3:0 = jb3:0;;
#else
jb3:0 = q[j31 + ___allzeros];;
kb3:0 = q[j31 + ___allzeros];;
jl3:0 = q[j31 + ___allones];;
kl3:0 = q[j31 + ___allones];;
#endif
// Call any initializers, including static constructors.
// For the non-c++ compiles we avoid the call overhead to the process
// ctors to reduce the overall cycle count. If the I/O, heap or interrupts
// are used then the appropriate initialisation rountines are called.
#ifdef _CPLUSPLUS
call ___ctorloop (NP); q[J27+4]=J27:24; q[K27+4]=K27:24;;
#else
XR0 = [j31 + ___ctor_table+1];;
XR0 = PASS R0;;
if xaeq, jump __done_clib_inits (NP); else, J16 = j31 + ___ctor_table+1;;
.call_init:
CJMP = [J16 += 1];;
cjmp_call (ABS)(NP); q[J27+4]=J27:24; q[K27+4]=K27:24;;
XR0 = [J16 + J31];;
XR0 = PASS R0;;
nop;;
if nxaeq, jump .call_init ;else, j4 = 0;; // main's argument count
#endif
// Call main. The C standard requires that the first argument
// passed to main be non-negative. We choose to pass 0 (the
// argument count), since the host environment is not capable
// of transmitting any host environment information, including
// the program name.
__done_clib_inits:
// Define the macro NO_ARGV is you do not want argc/argv support.
#ifndef NO_ARGV
call __getargv (NP); q[J27+4]=J27:24; q[K27+4]=K27:24;;
j4 = j8;;
#else
j4 = 0;; // main's argument count
#endif
j5 = __Argv;; // main's argument vector
call _main (NP); q[J27+4]=J27:24; q[K27+4]=K27:24;;
// Jump to the exit() routine, passing return value from main().
// exit() must not return.
jump _exit (NP); j4 = j8 + 0;;
_____system_start.end:
// Create the head of the static constructor array.
.extern _exit;
.extern _main;
.extern _ldf_defheap_base;
.extern _ldf_defheap_size;
.extern _ldf_jstack_base;
.extern _ldf_kstack_base;
// The following symbols are weak so that no linking error will occur if
// these symbols are not specified in the LDF. To use the alternate heap
// the LDF must define these symbols with appropriate values.
.weak _ldf_altheap_base;
.weak _ldf_altheap_size;
.weak _ldf_altheap_base2;
.weak _ldf_altheap_size2;
#ifndef NO_ARGV
.extern __getargv;
#endif
#ifdef _CPLUSPLUS
.extern ___ctorloop;
.section .gdt;
.global ___eh_gdt;
.var ___eh_gdt = -1;
.section .frt;
.global ___eh_frt;
.var ___eh_frt = -1;
#endif
.section ctor0;
.global ___ctor_table;
.var ___ctor_table = 0;
// Create the heap descriptor table and describe the default
// heap, which is the first entry in the heap descriptor
// table. The ts_exit.asm file declares a label for the end of
// this table.
.section heaptab;
// Create the heap descriptor table for MAXHEAPS multiple heaps
// that can be created and initialised for us at run-time.
#define MAXHEAPS 4
.global ___heaps;
.align 4; // __heaps is an array, must be quad-word aligned
.var ___heaps[3 * MAXHEAPS];
.___heaps.end:
.global ___nheaps;
.var ___nheaps = 0;
.___nheaps.end:
.global ___heaptab_start;
___heaptab_start:
.var = _ldf_defheap_base; // start of default heap
.var = _ldf_defheap_size; // size of default heap, unit==sizeof(char)
.var = 0; // id of default heap -- must be 0
.var = _ldf_altheap_base; // start of alternate heap
.var = _ldf_altheap_size; // size of alternate heap, unit==sizeof(char)
.var = 1; // id of alternate heap -- must be 1
.var = _ldf_altheap_base2;
.var = _ldf_altheap_size2;
.var = 2;
// The compiler may generate optimized loops in which a
// speculative read is done off either the high or the low end
// of an array. If the array is at the very beginning or end
// of a memory block (i.e. the speculative read accesses an
// illegal address), this won't work. Thus we ensure that
// there is a minimum 4-word buffer at each end of the two
// data sections (data1 and data2) used by the compiler for
// data objects. [Actually, a 1-word buffer at the low end
// would probably be enough, since arrays accessed with
// double- or quad-word reads would be aligned so as to
// increase the effective size of the buffer to 2 or 4 words.]
// These buffers can contain useful data since the optimized
// loops only read the data beyond the array bounds. A
// particular .ldf file may guarantee that one or both ends of
// the data1 or data2 sections will not be close to an illegal
// address. In such cases, the affected buffers could be
// eliminated.
.section data1;
// the arguments to main provide the data1 buffer
.align 4; // ___argv_string is an array, must be quad-word aligned
.var ___argv_string[1];
.weak ___argv_string;
.extern __Argv;
#if defined(__ADSPTS201__)
// The central location for storing values written to INTCTL,
// as part of a workaround for errata 03-00-0213.
// When writing to INTCTL, ensure you write the same value
// simultaneuosly to this location. Instead of reading INTCTL,
// read from this location instead.
.var _Save_INTCTL=0;
.global _Save_INTCTL;
#endif
.section data2;
.var ___data2_buf_lo[4];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -