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

📄 larith.asm

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	bne	LoopReturn:	rtsReturn_zero:	clrb	rts#endif#ifdef L_divmodhi4#ifndef mc68hc12/* 68HC12 signed divisions are generated inline (idivs).  */	declare_near __divmodhi4;;; D = numerator;; X = denominator;;;; Result:	D = D / X;;		X = D % X;; 	tsta	bpl	Numerator_pos	comb			; D = -D <=> D = (~D) + 1	coma	xgdx	inx	tsta	bpl	Numerator_neg_denominator_posNumerator_neg_denominator_neg:	comb			; X = -X	coma	addd	#1	xgdx	idiv	coma	comb	xgdx			; Remainder <= 0 and result >= 0	inx	rtsNumerator_pos_denominator_pos:	xgdx	idiv	xgdx			; Both values are >= 0	rts	Numerator_pos:	xgdx	tsta	bpl	Numerator_pos_denominator_posNumerator_pos_denominator_neg:	coma			; X = -X	comb	xgdx	inx	idiv	xgdx			; Remainder >= 0 but result <= 0	coma	comb	addd	#1	rts	Numerator_neg_denominator_pos:	xgdx	idiv	coma			; One value is > 0 and the other < 0	comb			; Change the sign of result and remainder	xgdx	inx	coma	comb	addd	#1	rts#endif /* !mc68hc12 */#endif#ifdef L_mulqi3	declare_near ___mulqi3;; short __mulqi3(signed char a, signed char b);;;	signed char a	-> register A;	signed char b	-> register B;; returns the signed result of A * B in register D.;	tsta	bmi	A_neg	tstb	bmi	B_neg	mul	rtsB_neg:	negb	bra	A_or_B_negA_neg:	nega	tstb	bmi	AB_negA_or_B_neg:	mul	coma	comb	addd	#1	rtsAB_neg:	negb	mul	rts#endif	#ifdef L_mulhi3	declare_near ___mulhi3;;;  unsigned short ___mulhi3(unsigned short a, unsigned short b);;	a = register D;	b = register X;#ifdef mc68hc12	pshx			; Preserve X	exg	x,y	emul	exg	x,y	pulx	rts#else#ifdef NO_TMP	;	; 16 bit multiplication without temp memory location.	; (smaller but slower)	;	pshx			; (4)	ins			; (3)	pshb			; (3)	psha			; (3)	pshx			; (4)	pula			; (4)	pulx			; (5)	mul			; (10) B.high * A.low	xgdx			; (3)	mul			; (10) B.low * A.high	abx			; (3)	pula			; (4)	pulb			; (4)	mul			; (10) B.low * A.low	pshx			; (4) 	tsx			; (3)	adda	1,x		; (4)	pulx			; (5)	rts			; (5) 20 bytes				; ---				; 91 cycles#else	stx	*_.tmp		; (4)	pshb			; (3)	ldab	*_.tmp+1	; (3)	mul			; (10) A.high * B.low	ldaa	*_.tmp		; (3)	stab	*_.tmp		; (3)	pulb			; (4)	pshb			; (4)	mul			; (10) A.low * B.high	addb	*_.tmp		; (4)	stab	*_.tmp		; (3)	ldaa	*_.tmp+1	; (3)	pulb			; (4)	mul			; (10) A.low * B.low	adda	*_.tmp		; (4)	rts			; (5) 24/32 bytes				; 77/85 cycles#endif#endif#endif#ifdef L_mulhi32;;;  unsigned long __mulhi32(unsigned short a, unsigned short b);;	a = register D;	b = value on stack;;	+---------------+;       |  B low	| <- 7,x;	+---------------+;       |  B high	| <- 6,x;	+---------------+;       |  PC low	|  ;	+---------------+;       |  PC high	|  ;	+---------------+;	|  Tmp low	|;	+---------------+;	|  Tmp high     |;	+---------------+;	|  A low	|;	+---------------+;	|  A high	|;	+---------------+  <- 0,x;;;      <B-low>    5,x;      <B-high>   4,x;      <ret>      2,x;      <A-low>    1,x;      <A-high>   0,x;	declare_near	__mulhi32#ifdef mc68hc12	ldy	2,sp	emul	exg	x,y	rts#else	pshx			; Room for temp value	pshb	psha	tsx	ldab	6,x	mul	xgdy			; A.high * B.high	ldab	7,x	pula	mul			; A.high * B.low	std	2,x	ldaa	1,x	ldab	6,x	mul			; A.low * B.high	addd	2,x	stab	2,x	tab	aby	bcc	N	ldab	#0xff	aby	inyN:	ldab	7,x	pula	mul			; A.low * B.low	adda	2,x	pulx			; Drop temp location	pshy			; Put high part in X	pulx	bcc	Ret	inxRet:	rts#endif	#endif#ifdef L_mulsi3;;      <B-low>    8,y;      <B-high>   6,y;      <ret>      4,y;	<tmp>	  2,y;      <A-low>    0,y;; D,X   -> A; Stack -> B;; The result is:;;	(((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low);;;	declare	__mulsi3#ifdef mc68hc12	pshd				; Save A.low	ldy	ARG(4),sp	emul				; A.low * B.high	ldy	ARG(6),sp	exg	x,d	emul				; A.high * B.low	leax	d,x	ldy	ARG(6),sp	puld	emul				; A.low * B.low	exg	d,y	leax	d,x	exg	d,y	ret#elseB_low	=	ARG(8)B_high	=	ARG(6)A_low	=	0A_high	=	2	pshx	pshb	psha	tsy;; If B.low is 0, optimize into: (A.low * B.high) << 16;	ldd	B_low,y	beq	B_low_zero;; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low);	cpx	#0	beq	A_high_zero	bsr	___mulhi3		; A.high * B.low;; If A.low is 0, optimize into: (A.high * B.low) << 16;	ldx	A_low,y	beq	A_low_zero		; X = 0, D = A.high * B.low	std	2,y;; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.;	ldd	B_high,y	beq	B_high_zero	bsr	___mulhi3		; A.low * B.high	addd	2,y	std	2,y;; Here, we know that A.low and B.low are not 0.;B_high_zero:	ldd	B_low,y			; A.low is on the stack	bsr	__mulhi32		; A.low * B.low	xgdx	tsy				; Y was clobbered, get it back	addd	2,yA_low_zero:				; See A_low_zero_non_optimized below	xgdxReturn:	ins	ins	ins	ins	ret;; ; A_low_zero_non_optimized:;; At this step, X = 0 and D = (A.high * B.low); Optimize into: (A.high * B.low) << 16;;	xgdx;	clra			; Since X was 0, clearing D is superfuous.;	clrb;	bra	Return; ----------------; B.low == 0, the result is:	(A.low * B.high) << 16;; At this step:;   D = B.low				= 0 ;   X = A.high				?;       A.low is at A_low,y		?;       B.low is at B_low,y		?;B_low_zero:	ldd	A_low,y	beq	Zero1	ldx	B_high,y	beq	Zero2	bsr	___mulhi3Zero1:	xgdxZero2:	clra	clrb	bra	Return; ----------------; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low);; At this step:;   D = B.low				!= 0 ;   X = A.high				= 0;       A.low is at A_low,y		?;       B.low is at B_low,y		?;A_high_zero:	ldd	A_low,y		; A.low	beq	Zero1	ldx	B_high,y	; B.high	beq	A_low_B_low	bsr	___mulhi3	std	2,y	bra	B_high_zero	; Do the (A.low * B.low) and the add.; ----------------; A.high and B.high are 0 optimize into: (A.low * B.low);; At this step:;   D = B.high				= 0 ;   X = A.low				!= 0;       A.low is at A_low,y		!= 0;       B.high is at B_high,y		= 0;A_low_B_low:	ldd	B_low,y			; A.low is on the stack	bsr	__mulhi32	bra	Return#endif#endif#ifdef L_map_data	.sect	.install2,"ax",@progbits	.globl	__map_data_section	.globl __data_image#ifdef mc68hc12	.globl __data_section_size#endif__map_data_section:#ifdef mc68hc12	ldx	#__data_image	ldy	#__data_section_start	ldd	#__data_section_size	beq	DoneLoop:	movb	1,x+,1,y+	dbne	d,Loop#else	ldx	#__data_image	ldy	#__data_section_start	bra	Start_mapLoop:	ldaa	0,x	staa	0,y	inx	inyStart_map:	cpx	#__data_image_end	blo	Loop#endifDone:#endif#ifdef L_init_bss	.sect	.install2,"ax",@progbits	.globl	__init_bss_section__init_bss_section:	ldd	#__bss_size	beq	Done	ldx	#__bss_startLoop:#ifdef mc68hc12	clr	1,x+	dbne	d,Loop#else	clr	0,x	inx	subd	#1	bne	Loop#endifDone:#endif#ifdef L_ctor; End of constructor table	.sect	.install3,"ax",@progbits	.globl	__do_global_ctors__do_global_ctors:	; Start from the end - sizeof(void*)	ldx	#__CTOR_END__-2ctors_loop:	cpx	#__CTOR_LIST__	blo	ctors_done	pshx	ldx	0,x	jsr	0,x	pulx	dex	dex	bra	ctors_loopctors_done:#endif#ifdef L_dtor	.sect	.fini3,"ax",@progbits	.globl	__do_global_dtors;;;; This piece of code is inserted in the _exit() code by the linker.;;__do_global_dtors:	pshb	; Save exit code	psha	ldx	#__DTOR_LIST__dtors_loop:	cpx	#__DTOR_END__	bhs	dtors_done	pshx	ldx	0,x	jsr	0,x	pulx	inx	inx	bra	dtors_loopdtors_done:	pula	; Restore exit code	pulb#endif#ifdef L_far_tramp#ifdef mc68hc12	.sect	.tramp,"ax",@progbits	.globl	__far_trampoline;; This is a trampoline used by the linker to invoke a function;; using rtc to return and being called with jsr/bsr.;; The trampoline generated is:;;;;	foo_tramp:;;		ldy	#foo;;		call	__far_trampoline,page(foo);;;; The linker transforms:;;;;		jsr	foo;;;; into;;		jsr	foo_tramp;;;; The linker generated trampoline and _far_trampoline must be in ;; non-banked memory.;;__far_trampoline:	movb	0,sp, 2,sp	; Copy page register below the caller's return	leas	2,sp		; address.	jmp	0,y		; We have a 'call/rtc' stack layout now				; and can jump to the far handler				; (whose memory bank is mapped due to the				; call to the trampoline).#endif#ifdef mc68hc11	.sect	.tramp,"ax",@progbits	.globl __far_trampoline;; Trampoline generated by gcc for 68HC11:;;;;	pshb;;	ldab	#%page(func);;	ldy	#%addr(func);;	jmp	__far_trampoline;;__far_trampoline:	psha				; (2) Save function parameter (high)	;; <Read current page in A>	psha				; (2)	;; <Set currenge page from B>	pshx				; (4)	tsx				; (3)	ldab	4,x			; (4) Restore function parameter (low)	ldaa	2,x			; (4) Get saved page number	staa	4,x			; (4) Save it below return PC	pulx				; (5)	pula				; (3)	pula				; (3) Restore function parameter (high)	jmp	0,y			; (4)#endif#endif#ifdef L_call_far#ifdef mc68hc11	.sect	.tramp,"ax",@progbits	.globl __call_a16	.globl __call_a32;;;; The call methods are used for 68HC11 to support memory bank switching.;; Every far call is redirected to these call methods.  Its purpose is to:;;;;  1/ Save the current page on the stack (1 byte to follow 68HC12 call frame);;  2/ Install the new page;;  3/ Jump to the real function;;;; The page switching (get/save) is board dependent.  The default provided;; here does nothing (just create the appropriate call frame).;;;; Call sequence (10 bytes, 13 cycles):;;;;	ldx #page			; (3);;	ldy #func			; (4);;	jsr __call_a16			; (6);;;; Call trampoline (11 bytes, 19 cycles):;;__call_a16:	;; xgdx				; (3)	;; <Read current page in A>	; (3) ldaa _current_page	psha				; (2)	;; <Set current page from B>	; (4) staa _current_page	;; xgdx				; (3)	jmp 0,y				; (4);;;; Call sequence (10 bytes, 14 cycles):;;;;	pshb				; (2);;	ldab #page			; (2);;	ldy  #func			; (4);;	jsr __call_a32			; (6);;;; Call trampoline (87 bytes, 57 cycles):;;__call_a32:	pshx				; (4)	psha				; (2)	;; <Read current page in A>	; (3) ldaa _current_page	psha				; (2)	;; <Set current page from B>	; (4) staa _current_page	tsx				; (3)	ldab	6,x			; (4) Restore function parameter	ldaa	5,x			; (4) Move PC return at good place	staa	6,x			; (4)	ldaa	4,x			; (4)	staa	5,x			; (4)	pula				; (3)	staa	4,x			; (4)	pula				; (3)	pulx				; (5)	jmp	0,y			; (4)#endif#endif#ifdef L_return_far#ifdef mc68hc11	.sect	.tramp,"ax",@progbits       .globl __return_void       .globl __return_16       .globl __return_32__return_void:	;; pulb	;; <Set current page from B> (Board specific)	;; rts__return_16:	;; xgdx	;; pulb	;; <Set current page from B> (Board specific)	;; xgdx	;; rts__return_32:	;; xgdy	;; pulb	;; <Set current page from B> (Board specific)	;; xgdy	;; rts	ins	rts#endif#endif.Lend:;-----------------------------------------; end required gcclib code;-----------------------------------------

⌨️ 快捷键说明

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