1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  linux_logo in x86_64 assembly language
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#    based on the code from ll_asm-0.36
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  By Vince Weaver <vince _at_ deater.net>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Modified to remove non-deterministic system calls
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# And to avoid reading from /proc
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
12eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov.include "logo.include"
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# offsets into the results returned by the uname syscall
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_SYSNAME,0
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_NODENAME,65
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_RELEASE,65*2
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_VERSION,(65*3)
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_MACHINE,(65*4)
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ U_DOMAINNAME,65*5
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# offset into the results returned by the sysinfo syscall
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ S_TOTALRAM,32
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Sycscalls
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_EXIT,    60
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_READ,     0
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_WRITE,    1
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_OPEN,     2
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_CLOSE,    3
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_SYSINFO, 99
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ SYSCALL_UNAME,   63
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ STDIN,0
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ STDOUT,1
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.equ STDERR,2
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.globl _start
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown_start:
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========================
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# PRINT LOGO
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========================
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# LZSS decompression algorithm implementation
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# by Stephan Walter 2002, based on LZSS.C by Haruhiko Okumura 1989
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# optimized some more by Vince Weaver
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# we used to fill the buffer with FREQUENT_CHAR
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# but, that only gains us one byte of space in the lzss image.
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# the lzss algorithm does automatic RLE... pretty clever
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# so we compress with NUL as FREQUENT_CHAR and it is pre-done for us
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov     $(N-F), %ebp   	     	# R
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov  	$logo, %esi		# %esi points to logo (for lodsb)
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$out_buffer, %edi	# point to out_buffer
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rdi	     		# save this value for later
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor	%ecx, %ecx
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndecompression_loop:
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb			# load in a byte
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov 	$0xff, %bh	# re-load top as a hackish 8-bit counter
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov 	%al, %bl	# move in the flags
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntest_flags:
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$logo_end, %esi # have we reached the end?
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done_logo  	# ! if so, exit
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr 	$1, %ebx	# shift bottom bit into carry flag
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jc	discrete_char	# ! if set, we jump to discrete char
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownoffset_length:
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsw                   # get match_length and match_position
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov %eax,%edx		# copy to edx
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    			# no need to mask dx, as we do it
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				# by default in output_loop
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr $(P_BITS),%eax
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	add $(THRESHOLD+1),%al
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov %al,%cl             # cl = (ax >> P_BITS) + THRESHOLD + 1
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				  #                       (=match_length)
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownoutput_loop:
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	and 	$POSITION_MASK,%dh  	# mask it
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov 	text_buf(%rdx), %al	# load byte from text_buf[]
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc 	%edx	    		# advance pointer in text_buf
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstore_byte:
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# store it
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov     %al, text_buf(%rbp)	# store also to text_buf[r]
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc 	%ebp 			# r++
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	and 	$(N-1), %bp		# mask r
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	loop 	output_loop		# repeat until k>j
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	or	%bh,%bh			# ! if 0 we shifted through 8 and must
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jnz	test_flags		# re-load flags
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp 	decompression_loop
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndiscrete_char:
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# load a byte
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%ecx			# we set ecx to one so byte
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# will be output once
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# (how do we know ecx is zero?)
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp     store_byte              # and cleverly store it
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# end of LZSS code
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone_logo:
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop 	%rbp			# get out_buffer and keep in bp
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%ecx		# move out_buffer to ecx
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	write_stdout		# print the logo
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#  Setup
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsetup:
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$strcat,%edx		# use rdx as call pointer (smaller op)
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==========================
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# PRINT VERSION
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==========================
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push 	$SYSCALL_UNAME		# uname syscall
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%rax			# in 3 bytes
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$uname_info,%edi	# uname struct (0 extend address)
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	syscall				# do syscall
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%edi		# point %edi to out_buffer
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_SYSNAME),%esi	# os-name from uname "Linux"
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%rdx			# call strcat
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$ver_string,%esi		# source is " Version "
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%rdx			        # call strcat
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rsi  				# save our .txt pointer
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_RELEASE),%esi    # version from uname "2.4.1"
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%rdx				# call strcat
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rsi  			# restore .txt pointer
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# source is ", Compiled "
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%rdx			# call strcat
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rsi  			# store for later
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_VERSION),%esi	# compiled date
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%rdx			# call strcat
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%ecx		# move out_buffer to ecx
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0xa,%ax		# store linefeed on end
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosw				# and zero
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%rdx			# call strcat
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	center_and_print	# center and print
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#===============================
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Middle-Line
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#===============================
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmiddle_line:
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Load /proc/cpuinfo into buffer
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rdx			# save call pointer
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push	$SYSCALL_OPEN		# load 5 [ open() ]
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%rax			# in 3 bytes
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$cpuinfo,%edi		# '/proc/cpuinfo'
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	xor	%esi,%esi		# 0 = O_RDONLY <bits/fcntl.h>
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cdq				# clear edx in clever way
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	syscall				# syscall.  fd in eax.
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# we should check that eax>=0
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	%eax,%edi		# save our fd
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	xor	%eax,%eax		# SYSCALL_READ make== 0
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$disk_buffer,%esi
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$16,%dh		 	# 4096 is maximum size of proc file #)
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# we load sneakily by knowing
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# 16<<8 = 4096. be sure edx clear
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	syscall
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push	$SYSCALL_CLOSE		# close (to be correct)
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%rax
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	syscall
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=============
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Number of CPUs
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=============
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownnumber_of_cpus:
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor	%ebx,%ebx		# chip count
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# $disk_buffer still in %rsi
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbogo_loop:
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	(%rsi), %eax		# load 4 bytes into eax
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%esi			# increment pointer
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al			# check for end of file
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done_bogo
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Grrr, due to a bug in binutils 2.18.50.0.9
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        #   (which unfortunately shipped with Fedora 10)
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   http://sourceware.org/bugzilla/show_bug.cgi?id=6878
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   We can't use the apostrophe character
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#       cmp     $('o'<<24+'g'<<16+'o'<<8+'b'),%eax
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        cmp     $(0x6f<<24+0x67<<16+0x6f<<8+0x62),%eax
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				        # "bogo" in little-endian
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	bogo_loop		# ! if not equal, keep going
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	add	$2,%ebx			# otherwise, we have a bogo
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# 2 times too for future magic
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp	bogo_loop
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone_bogo:
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lea	one-6(%rbx,%rbx,2), %esi
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				    	# Load into esi
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# [one]+(num_cpus*6)
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					#
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# the above multiplies by three
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# esi = (ebx+(ebx*2))
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 				# and we double-incremented ebx
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# earlier
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%edi		# move output buffer to edi
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rdx			# restore call pointer
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%rdx			# copy it (call strcat)
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$' ',%al		# print a space
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x20,%al		# print a space
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push %rbx
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push %rdx			# store strcat pointer
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# MHz
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_mhz:
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#       mov     $('z'<<24+'H'<<16+'M'<<8+' '),%ebx
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        mov     $(0x7a<<24+0x48<<16+0x4d<<8+0x20),%ebx
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			   		# find ' MHz' and grab up to .
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	                                # we are little endian
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$'.',%ah
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x2e,%ah
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# below is same as "sub $(strcat-find_string),%edx
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# gas won't let us force the one-byte constant
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	.byte 0x83,0xEA,strcat-find_string
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%rdx			# call find string
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebx,%eax  		# clever way to get MHz in, sadly
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ror	$8,%eax			# not any smaller than a mov
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosl
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Chip Name
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=========
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchip_name:
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#       mov     $('e'<<24+'m'<<16+'a'<<8+'n'),%ebx
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        mov     $(0x65<<24+0x6d<<16+0x61<<8+0x6e),%ebx
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# find 'name\t: ' and grab up to \n
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# we are little endian
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$' ',%ah
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x20,%ah
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%rdx	   		# call find_string
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	skip_spaces
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rdx
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rbx                    # restore chip count
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rsi
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call    *%rdx                   # ' Processor'
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb    $2,%bl
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne     print_s
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc     %rsi   			# ! if singular, skip the s
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_s:
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        call    *%rdx                   # 's, '
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        push    %rsi                    # restore the values
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %rdx
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# RAM
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push	%rdi
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	push    $SYSCALL_SYSINFO	# sysinfo() syscall
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%rax
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$sysinfo_buff,%edi
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	syscall
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	pop	%rdi
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# The following has to be a 64 bit load, to support
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Ram > 4GB
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	(sysinfo_buff+S_TOTALRAM),%rax	# size in bytes of RAM
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr	$20,%rax		# divide by 1024*1024 to get M
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adc	$0, %eax		# round
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call num_to_ascii
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop  %rdx	 		# restore strcat pointer
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rsi	 		# print 'M RAM, '
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	*%rdx			# call strcat
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rsi
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Bogomips
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#========
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#       mov     $('s'<<24+'p'<<16+'i'<<8+'m'),%ebx
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        mov     $(0x73<<24+0x70<<16+0x69<<8+0x6d),%ebx
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# find 'mips\t: ' and grab up to \n
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0xa,%ah
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	find_string
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rsi	   		# bogo total follows RAM
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call 	*%rdx			# call strcat
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rsi
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ebp,%ecx		# point ecx to out_buffer
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rcx
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	center_and_print	# center and print
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Print Host Name
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownlast_line:
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov     %ebp,%edi		# point to output_buffer
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(uname_info+U_NODENAME),%esi	# host name from uname()
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call    *%rdx			# call strcat
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rcx	      		# ecx is unchanged
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	center_and_print	# center and print
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rcx			# (.txt) pointer to default_colors
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	write_stdout
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# Exit
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownexit:
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$SYSCALL_EXIT		# Put exit syscall in rax
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rax
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor	%edi,%edi		# Make return value $0
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	syscall
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# FIND_STRING
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#=================================
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   ah is char to end at
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   ebx is 4-char ascii string to look for
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#   edi points at output buffer
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfind_string:
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$disk_buffer-1,%esi	# look in cpuinfo buffer
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfind_loop:
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%esi
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$0, (%rsi)		# are we at EOF?
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done			# ! if so, done
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	(%rsi), %ebx		# do the strings match?
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	find_loop		# ! if not, loop
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# ! if we get this far, we matched
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfind_colon:
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# repeat till we find colon
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cmp	$':',%al
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0x3a,%al
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	find_colon
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownskip_spaces:
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# skip spaces
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0x20,%al		# Loser new intel chips have lots??
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	skip_spaces
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstore_loop:
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	done
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	%ah,%al			# is it end string?
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je 	almost_done		# ! if so, finish
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	cmp	$'\n',%al
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0xa,%al
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	je	almost_done
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# ! if not store and continue
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jmp	store_loop
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownalmost_done:
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	movb	 $0, (%rdi)	        # replace last value with NUL
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone:
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# strcat
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstrcat:
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lodsb				# load a byte from [ds:esi]
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb				# store a byte to [es:edi]
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	$0,%al			# is it zero?
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	strcat			# ! if not loop
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dec	%edi			# point to one less than null
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret				# return
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==============================
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# center_and_print
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#==============================
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# string to center in ecx
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncenter_and_print:
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %rdx			# save strcat pointer
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rcx			# save the string pointer
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%edi			# move to a clear buffer
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	%rdi			# save for later
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$('['<<8+27),%ax	# we want to output ^[[
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$(0x5b<<8+27),%ax	# we want to output ^[[
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosw
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cdq	      			# clear dx
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstr_loop2:				# find end of string
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%edx
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$0,(%rcx,%rdx)		# repeat till we find zero
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	str_loop2
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$81	 		# one added to cheat, we don't
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# count the trailing '\n'
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rax
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmp	%eax,%edx		# see if we are >=80
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jl	not_too_big		# ! if so, don't center
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$80
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rdx
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownnot_too_big:
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	sub	%edx,%eax		# subtract size from 80
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	shr	%eax			# then divide by 2
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call	num_to_ascii		# print number of spaces
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	mov	$'C',%al		# tack a 'C' on the end
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	$0x43,%al		# tack a 'C' on the end
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# ah is zero from num_to_ascii
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosw				# store C and a NULL
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop  %rcx			# pop the pointer to ^[[xC
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	call write_stdout		# write to the screen
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndone_center:
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop  %rcx			# restore string pointer
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     				# and trickily print the real string
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop %rdx			# restore strcat pointer
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# WRITE_STDOUT
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	#================================
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# ecx has string
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# eax,ebx,ecx,edx trashed
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownwrite_stdout:
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %rdx
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push	$SYSCALL_WRITE		# put 4 in eax (write syscall)
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rax     		# in 3 bytes of code
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cdq   	      			# clear edx
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	lea	1(%rdx),%edi		# put 1 in ebx (stdout)
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					# in 3 bytes of code
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	mov	%ecx,%esi
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstr_loop1:
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc	%edx
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cmpb	$0,(%rcx,%rdx)		# repeat till zero
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jne	str_loop1
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	syscall  			# run the syscall
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop	%rdx
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	##############################
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# num_to_ascii
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	##############################
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# ax = value to print
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	# edi points to where we want it
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownnum_to_ascii:
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    $10
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rbx
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	xor     %ecx,%ecx       # clear ecx
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndiv_by_10:
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	cdq                     # clear edx
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	div     %ebx            # divide
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	push    %rdx            # save for later
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	inc     %ecx            # add to length counter
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	or      %eax,%eax       # was Q zero?
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	jnz     div_by_10       # ! if not divide again
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownwrite_out:
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pop     %rax            # restore in reverse order
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	add     $0x30, %al      # convert to ASCII
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	stosb                   # save digit
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	loop    write_out       # loop till done
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#===========================================================================
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	section .data
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#===========================================================================
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.data
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownver_string:	.ascii	" Version \0"
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncompiled_string:	.ascii	", Compiled \0"
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprocessor:		.ascii  " Processor\0"
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browns_comma:		.ascii  "s, \0"
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownram_comma:	.ascii	"M RAM, \0"
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbogo_total:	.ascii	" Bogomips Total\n\0"
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndefault_colors:	.ascii "\033[0m\n\n\0"
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncpuinfo:	.ascii	"/proc/cpuinfo\0"
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownone:	.ascii	"One\0\0\0"
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntwo:	.ascii	"Two\0\0\0"
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthree:	.ascii	"Three\0"
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfour:	.ascii	"Four\0"
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
566eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov.include	"logo.lzss_new"
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndisk_buffer:
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "processor	: 0\n"
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "vendor_id	: GenuineIntel\n"
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu family	: 15\n"
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "model		: 6\n"
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "model name	: Intel(R) Xeon(TM) CPU 3.46GHz\n"
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "stepping	: 4\n"
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu MHz		: 3200.000\n"
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cache size	: 2048 KB\n"
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "physical id	: 0\n"
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "siblings	: 2\n"
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "core id		: 0\n"
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu cores	: 2\n"
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "apicid		: 0\n"
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "initial apicid	: 0\n"
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fpu		: yes\n"
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fpu_exception	: yes\n"
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpuid level	: 6\n"
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "wp		: yes\n"
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc pebs bts pni dtes64 monitor ds_cpl vmx est cid cx16 xtpr pdcm lahf_lm tpr_shadow\n"
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "bogomips	: 6934.38\n"
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "clflush size	: 64\n"
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cache_alignment	: 128\n"
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "address sizes	: 36 bits physical, 48 bits virtual\n"
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "power management:\n"
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\n"
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "processor	: 1\n"
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "vendor_id	: GenuineIntel\n"
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu family	: 15\n"
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "model		: 6\n"
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "model name	: Intel(R) Xeon(TM) CPU 3.46GHz\n"
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "stepping	: 4\n"
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu MHz		: 3200.000\n"
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cache size	: 2048 KB\n"
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "physical id	: 1\n"
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "siblings	: 2\n"
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "core id		: 0\n"
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpu cores	: 2\n"
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "apicid		: 4\n"
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "initial apicid	: 4\n"
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fpu		: yes\n"
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "fpu_exception	: yes\n"
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cpuid level	: 6\n"
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "wp		: yes\n"
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc pebs bts pni dtes64 monitor ds_cpl vmx est cid cx16 xtpr pdcm lahf_lm tpr_shadow\n"
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "bogomips	: 6934.13\n"
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "clflush size	: 64\n"
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "cache_alignment	: 128\n"
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "address sizes	: 36 bits physical, 48 bits virtual\n"
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "power management:\n\0"
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuname_info:
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "Linux\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "domori\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "2.6.29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "#1 SMP Mon May 4 09:51:54 EDT 2009\0\0"
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsysinfo_buff:
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.long 0,0,0,0,0,0,0,0,2048*1024*1024,0,0,0,0,0,0,0
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#============================================================================
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#	section .bss
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#============================================================================
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.bss
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.lcomm  text_buf, (N+F-1)
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown.lcomm	out_buffer,16384
649