⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 startup.asm

📁 < C及C++嵌入式编程实例精选>>一书2-9章的配套源码.
💻 ASM
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 
; Filename:	    startup.asm
;
; Description:  Startup code for Borland C/C++.
;
; Notes:        This module should be specified first during linking.
;
; Warnings:	    The order of the segments within this file matters.
;
; 
; Copyright (c) 1998 by Michael Barr.  This software is placed into
; the public domain and may be used for any purpose.  However, this
; notice must not be changed or removed and no warranty is either
; expressed or implied by its publication or distribution.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    NAME    startup

    ;
    ; Global Variables
    ;
	PUBLIC 	_errno				; Required by the Borland libraries.
    PUBLIC  __psp				; Required for dynamic memory allocation.
    PUBLIC  __brklvl			; Required for dynamic memory allocation.
    PUBLIC  __heapbase			; Required for dynamic memory allocation.
    PUBLIC	__heaptop			; Required for dynamic memory allocation.

    ;
    ; Functions Defined Externally
    ;
	EXTRN	_main : FAR

    ;
    ; Constants
    ;
	stack_size EQU 1024			; By default, create a 1-kbyte stack.
	ram_size   EQU 2000h		; The Arcom board has 2000h pages of RAM.

	PCB        EQU 0ff00h		; Base of the Peripheral Control Block.
    GCS0ST     EQU PCB + 80h	; General-purpose chip select 0 start.
    GCS0SP	   EQU PCB + 82h	; General-purpose chip select 0 stop.
    GCS1ST     EQU PCB + 84h	; General-purpose chip select 1 start.
    GCS1SP	   EQU PCB + 86h	; General-purpose chip select 1 stop.

	;
	; Initializer/Terminator Structure Format (used by C++ modules)
	;
	Initializer	STRUC

		ctype	 DB	?		; Code Segment Type (0 = near, 1 = far)
		priority DB	?		; Priority (0 = highest, 0xff = lowest)
		foffset	 DW	?		; Function Pointer (Offset)
		fsegment DW	?		; Function Pointer (Segment)

	Initializer	ENDS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Segment:	    _text
;
; Description:	The following segment contains the startup code.
;
; Notes:        If desired, this segment can be located in ROM.
;
; Warnings:	    The terminators are not executed, since embedded
;               applications are not expected to complete and exit.
;       		However, an _exit_ segment must still be declared
;               here, for compatibility with existing C++ libraries.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_text SEGMENT PARA PUBLIC 'CODE'

	ASSUME	CS:_text

_startup PROC FAR
	;
	; Disable interrupts and set the direction flag.
	;
	cli
	cld

	;
	; Perform hardware initializations that may not have been
    ; done by the hardware initialization code in EEPROM.
    ;
    mov     dx, GCS0ST
    mov     ax, 7000h
    out     dx, ax

    mov     dx, GCS0SP
    mov     ax, 710Ah
    out     dx, ax

    mov     dx, GCS1ST
    mov     ax, 7100h
    out     dx, ax

    mov     dx, GCS1SP
    mov     ax, 720Ah
    out     dx, ax

	;
	; Initialize the segment registers.
	;
	mov		ax, dgroup
	mov		ds, ax
	mov		es, ax
	ASSUME	ds:dgroup, es:dgroup

initData:
	;
	; Zero the uninitialized data segment.
	;
	xor		ax, ax
	mov		di, offset dgroup:bss_start
	mov		cx, offset dgroup:data_end
	sub		cx, di
	shr		cx, 1
	jcxz	initStack
	rep		stosw

initStack:
	;
	; Initialize the stack.
	;
	mov		ax, _stack
	mov		ss, ax
	mov		sp, offset stack_top
	ASSUME	ss:_stack

initHeap:
    ; 
    ; Initialize the heap.
    ;
    mov		ax, _farheap				; heapBase
    inc     ax

    mov		[__brklvl + 2], ax
    mov     [__brklvl], 0000h
    mov		[__heapbase + 2], ax
    mov     [__heapbase], 0000h
    mov     [__psp], ax

    mov		bx, ram_size				; heapEnd
    mov     [__heaptop + 2], bx
    mov     [__heaptop], 0000h

    mov     dx, _farheap
    mov     ds, dx
    ASSUME	ds:_farheap

    mov     [id], 'Z'
    mov		[owner], 0
	sub		bx, ax
    mov     [npages], bx

initModules:
	;
	; Call any static initializers found in the _init_ segment.  
	; The C++ language guarantees that these functions are called
	; before main().  
	;
    ; The following registers are used.
	; 	SI - offset of the next initializer
	; 	DI - offset of the last initializer
	; 	CX - number of initializers remaining
	; 	BX - current initializer
	; 	AH - current priority
	;
	mov		si, offset igroup:init_start
	mov		di, offset igroup:init_end
    mov     ax, dgroup
    mov     ds, ax
	mov		ax, igroup
	mov		es, ax
	ASSUME	ds:dgroup, es:nothing

	mov		ax, di
	sub		ax, si
	sub		dx, dx
	mov		cx, SIZE Initializer
	idiv	cx
	mov		cx, ax					; CX has total number of initializers.
	jcxz	callMain
	sub		ah, ah					; AH has current priority (start at 0).

firstInitializer:
	mov		bx, si					; Restart, from the top of the table.

nextInitializer:
	cmp		bx, di					; Are there initializers left to check?
	jae		nextPriority			; If not, try the next priority.
	cmp		es:[bx.priority], ah	; Check this initializer's priority.
	jne		tryNextInitializer		; If it's not a match, try the next.

	push	es
	push	ax
	push	bx
	push	cx
	push	si
	push	di

	call	dword ptr es:[bx.foffset]	; Call the initializer

	pop		di
	pop		si
	pop		cx
	pop		bx
	pop		ax
	pop		es

	dec		cx							; Decrement number of initializers.
	jz		callMain					; If zero left, continue.

tryNextInitializer:
	add		bx, SIZE Initializer
	jmp		nextInitializer

nextPriority:
	inc		ah					; Process the next priority.
	jmp		firstInitializer

callMain:
	;
	; Enable interrupts and transfer control to C/C++.
	;
	sti
	call	_main

	;
	; A return from main() is unexpected.  Halt the processor.
	;
	hlt

_startup endp

_text ENDS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Segments:     _init_, _initend_, _exit_, _exitend_
;
; Description:  The following segments are used for C++ initializers
;               and terminators.  
;
; Notes:        If possible, these segments should be located in ROM.
;
; Warnings:	    The terminators are not executed, since embedded
;               applications are not expected to complete and exit.
;       	    However, an _exit_ segment must still be declared
;               here, for compatibility with existing libraries.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_init_ SEGMENT PARA PUBLIC 'INITDATA'

	init_start LABEL DWORD

_init_ ENDS

igroup GROUP _init_


_initend_ SEGMENT BYTE PUBLIC 'INITDATA'

	init_end LABEL DWORD

_initend_ ENDS

igroup GROUP _initend_


_exit_ SEGMENT DWORD PUBLIC 'EXITDATA'

	exit_start LABEL DWORD

_exit_ ENDS

igroup GROUP _exit_


_exitend_ SEGMENT BYTE PUBLIC 'EXITDATA'

	exit_end LABEL DWORD

	DB 16 DUP (?)			; Force the next segment to a new paragraph

_exitend_ ENDS

igroup GROUP _exitend_


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Segments:	    _data, _bss, _bssend, _stack, _farheap
;
; Description:  The following segments are used for the initialized 
;               and uninitialized data, stack, and heap, respectively.
;
; Notes:        These segments must be located in RAM.  In fact, the 
;               _farheap segment will contain whatever RAM is left over
;               after the others are allocated space.
;
; Warnings:	    For compatibility with Borland C/C++, the order of
;               these segments must not be changed.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_data SEGMENT PARA PUBLIC 'DATA'

	data_start LABEL BYTE		; Mark the start of the initialized data.

_data ENDS

dgroup GROUP _data 


_bss SEGMENT WORD PUBLIC 'BSS'

	bss_start LABEL BYTE		; Mark the start of the uninitialized data.

    _errno     DW ?
    __psp      DW ?
    __brklvl   DW ?
               DW ?
    __heapbase DW ?
			   DW ?
    __heaptop  DW ?
			   DW ?

_bss ENDS

dgroup GROUP _bss 


_bssend SEGMENT WORD PUBLIC 'BSSEND'

	DW ?						; Give a fixed size for proper alignment.
	data_end LABEL WORD			; Mark the end of the uninitialized data.

_bssend	ENDS

dgroup GROUP _bssend


_stack SEGMENT PARA STACK 'STACK'

	DB stack_size DUP (?)	 	; Reserve space for the stack.

	EVEN
    stack_top DW ?

_stack ENDS


_farheap SEGMENT PARA PUBLIC 'FARHEAP'

    id 		DB ?
    owner 	DW ?
    npages 	DW ?

    DB 11 DUP (?)				; Round the segment up to a full page.

_farheap ENDS


END	_startup			; End module and declare _startup as entry point.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -