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

📄 libc.asm

📁 A simple C compiler source code.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
%ifdef	__PIC__	__GET_GOT	mov	ebx,__EXT_VAR(__envp)	mov	ebx,[ebx]%else	mov	ebx,[__envp]%endif	mov	edx,edi	cld	xor	eax,eax        or	ecx,byte -1	repne	scasb	not	ecx	dec	ecx	mov	eax,ecx.next_var:	mov	ecx,eax	mov	esi,edx	mov	edi,[ebx]	test	edi,edi	jz	.ret	rep	cmpsb	jz	.found	add	ebx,byte 4	jmps	.next_var.found:	inc	edi		;assume = is next.ret:	mov	[__eax],edi	popa	ret;size_t strlen(const char *s);;<EDX	*s;;>EAXstrlen:	push	edx	__ADJUST_CDECL3 4*1,eax	mov	edx,eax.real:%if __OPTIMIZE__=__O_SPEED__	push	ecx	test	dl,3	jz	.boucle	cmp	byte[eax],0	jz	.strfi	cmp	byte[eax+1],0	jz	.ret1	cmp	byte[eax+2],0	jnz	.align	add	eax,byte 2	jmps	.strfi.align:	add	eax,byte 3	and	eax,byte -4.boucle:		;normally the whole loop is 7 cycles (for 8 bytes)	mov	ecx,dword[eax]	test	cl,cl	jz	.strfi	test	ch,ch	jz	.ret1	test	ecx,0xFF0000	jz	.ret2	shr	ecx,24	jz	.ret3	mov	ecx,dword[eax+8]	test	cl,cl	jz	.ret4	test	ch,ch	jz	.ret5	test	ecx,0xFF0000	jz	.ret6	add	eax,byte 8	shr	ecx,4	jnz	.boucle	dec	eax	jmps	.strfi.ret1:	inc	eax	jmps	.strfi.ret2:	add	eax,byte 2	jmps	.strfi.ret3:	add	eax,byte 3	jmps	.strfi.ret4:	add	eax,byte 4	jmps	.strfi.ret5:	dec	eax.ret6:	add	ecx,byte 6.strfi:	sub	eax,edx	pop	ecx%else		;__O_SIZE__	xor	eax,eax.boucle:	cmp	byte[edx+eax],1	inc	eax	jnc	.boucle	dec	eax%endif		;__OPTIMIZE__	pop	edx	ret;itoa (unsigned long value, char *string, int radix);;print 32 bit number as binary,octal,decimal,or hexadecimal value;;<EAX	unsigned long value;<EDI	char *string;<ECX	base    (2, 8, 10, 16, or another one)itoa:	pusha	mov	edi,edx	__ADJUST_CDECL3 4*8,eax,edi,ecx.real:.now:	call	.printB	mov	byte [edi],0	;zero terminate the string 	popa	ret.printB:	sub	edx,edx 	div	ecx 	test	eax,eax 	jz	.print0	push	edx	call	.printB	pop	edx.print0:	add	dl,'0'	cmp	dl,'9'	jle	.print1	add	dl,0x27.print1:	mov	[edi],dl 	inc	edi 	ret;int sprintf(char *str, const char *format, ...);;sprintf:	pusha		lea	edx,[esp + 4*8 + 12]	;preload argument (dangerous?)	mov	esi,[esp + 4*8 + 8]	;*format	mov	edi,[esp + 4*8 + 4]	;*str	push	edi	cld.boucle:	lodsb	test	al,al	jz	.out_pf	cmp	al,'%'	jz	.gest_spec;	cmp	al,'\'		;is it really needed?;	jz	.gest_spec2	;or compiler expands these characters?.store:	stosb	jmps	.boucle.gest_spec:	mov	ebx,[edx]	lodsb	_mov	ecx,10	cmp	al,'d'	jz	.gestf	_mov	ecx,16	cmp	al,'x'	jz	.gestf	_mov	ecx,8	cmp	al,'o'	jz	.gestf	_mov	ecx,2	cmp	al,'b'	jz	.gestf	cmp	al,'c'	jz	.store	cmp	al,'s'	jnz	.boucle	test	ebx,ebx		;NULL check	jz	.allok.copyit:			;copy string in args to output buffer	mov	al,[ebx]	test	al,al		;string is null terminated	jz	.allok	stosb	inc	ebx	jmps	.copyit.gestf:	pusha	mov	eax,ebx	call	itoa.printB	mov	byte [edi],0	;zero terminate the string 	popa.stl:	cmp	byte [edi],1	inc	edi	jnc	.stl	dec	edi.allok:	add	edx,byte 4	jmps	.boucle;.gest_spec2:;	lodsb;	mov	ah,__n;	cmp	al,'n';	jz	.s2;	mov	ah,__t;	cmp	al,'t';	jnz	.boucle;.s2:;	mov	al,ah;	stosb;	jmps	.boucle.out_pf:	xor	al,al	stosb	pop	edx	sub	edi,edx	dec	edi		;do not write trailing 0	mov	[__eax],edi	popa	ret;int printf(const char *format, ...);;uses rather dangerous approachprintf:%define _sf	0x1000	sub	esp,_sf			;create buffer (dangerous!!)    	pusha	mov	ebp,[esp + 4 * 8 + _sf]	;save return address	lea	esi,[esp + 4 * 8]	;here will our buffer begin	add	esp,4 * 8 + _sf		;rewind stack back	mov	[esp],esi		;replace return address with buffer	call	sprintf	mov	[esp],ebp		;restore return address	sub	esp,4 * 8 + _sf		;substitute stack	sys_write STDOUT,esi,eax	mov	[__eax + _sf],eax	popa	add	esp,_sf	ret%undef	_sf;int inet_aton(const char *cp, struct in_addr *inp);;convert IP address ascii string to 32 bit network oriented;;<ESI	*cp;<EDI	*inp;;>EAXinet_aton:	push	esi	push	edi	push	edx	mov	esi,eax	mov	edi,edx	__ADJUST_CDECL3	4*3,esi,edi	cld	_mov	ecx,4; convert xx.xx.xx.xx  to  network notation.conv:	xor	edx,edx.next:	lodsb	sub	al,'0'	jb	.loop1	add	edx,edx	lea	edx,[edx+edx*4]	add	dl,al	jmps	.next.loop1:	mov	al,dl	stosb	loop	.next	xor	eax,eax		;assume address was valid	pop	edx	pop	edi	pop	esi	ret;long strtol(const char *nptr, char **endptr, int base);;convert string in npt to a long integer value;according to given base (between 2 and 36);if enptr if not 0, it is the end of the string;else the string is null-terminated;;<EDI	const char *nptr;<ESI	char **endptr, or 0 if string is null-terminated;<ECX	int base (2, 8, 10, 16, or another one max=36);;>EAXstrtol:	push	edi        push	esi        push	ebx        push	ecx	mov	edi,eax	mov	esi,edx	__ADJUST_CDECL3 4*4,edi,esi,ecx	test	ecx,ecx	jnz	.base_ok	_mov	ecx,10		;default base to use.base_ok:        xor	eax,eax	xor	ebx,ebx.parse1:	cmp	byte [edi],32	jnz	.parse2        inc	edi        jmps	.parse1.parse2:	cmp	word[edi],'0x'        jnz	.next        _mov	ecx,16	add	edi,byte 2.next:	mov	bl,[edi]	sub	bl,'0'        jb	.done        cmp	bl,9        jbe	.ok        sub	bl,7        cmp	bl,35        jbe	.ok        sub	bl,32.ok:	imul	ecx	add	eax,ebx        inc	edi        cmp	edi,esi	jnz	.next.done:	pop	ecx        pop	ebx        pop	esi        pop	edi	ret;;unused functions;%macro _UNUSED_ 0;;convert 32 bit number to hex string;;>EAX;<EDILongToStr:	pushad	sub	esp,4	mov	ebp,esp	mov	[edi],word "0x"	inc	edi	inc	edi	mov	esi,edi	push	esi	mov     [ebp],eax	_mov ecx,16	;10 - decimal	_mov esi,0.l1:        inc     esi	xor	edx,edx	mov	eax,[ebp]	div	ecx	mov	[ebp],eax	mov     al,dl;dec convertion;	add	al,'0';	add	al,0x90;	daa;	adc	al,0x40;	daa;hex convertion	cmp	al,10	sbb	al,0x69	das        stosb	xor	eax,eax	cmp	eax,[ebp]	jnz	.l1        stosb	pop	ecx	xchg	ecx,esi        shr	ecx,1	jz	.l3	xchg	edi,esi	dec	esi	dec	esi.l2:        mov	al,[edi]	xchg	al,[esi]	stosb	dec     esi	loop    .l2.l3:	add	esp,4	popad	ret;;convert string to 32 bit number;;<EDI;>EAXStrToLong:	push	ebx	push	ecx	push	edi	_mov	eax,0	_mov	ebx,10	_mov	ecx,0.next:	mov	cl,[edi]	sub	cl,'0'	jb	.done	cmp	cl,9	ja	.done	mul	bx	add	eax,ecx;	adc	edx,0	;for 64 bit	inc	edi	jmp short .next.done:	pop	edi	pop	ecx	pop	ebx	retstrlen2:%if  __OPTIMIZE__=__O_SIZE__	push	edi	mov	edi,[esp + 8]	mov	eax,edi	dec	edi.l1:	inc	edi	cmp	[edi],byte 0	jnz	.l1	xchg	eax,edi	sub	eax,edi	pop	edi%else; (NK); note: below is classic variant of strlen; if not needed to save ecx register then size of classic code; will be same as above ; remark: fastcall version of strlen will on 2 bytes less than cdecl	push	esi	push	ecx	mov	esi,[esp + 12]	xor	eax,eax        or	ecx,-1	repne	scasb	not	ecx	mov	eax,ecx	dec	eax	pop	ecx	pop	esi%endif	_leave%endmacro ;_UNUSED_UDATASEG;;store them within caller's image;common	errno	4	;guess whatcommon	__cc	4	;calling convention (how many registers for fastcall)			;0 = cdeclcommon	__envp	4	;envp, for getenv()END

⌨️ 快捷键说明

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