www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/09/27/03:15:22

From: "M. Schulter" <mschulter AT value DOT net>
Newsgroups: comp.os.msdos.djgpp
Subject: DJGPP humor: lightyr.s (long long)
Date: 25 Sep 1997 23:15:10 GMT
Organization: Value Net Internetwork Services Inc.
Lines: 205
Message-ID: <60er9u$5qp$2@vnetnews.value.net>
NNTP-Posting-Host: value.net
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Hi, there.

Here's a standalone GAS program with a bit of humor: please enjoy. I'm not
sure if the fact this was created in Emacs asm mode has anything to do
with the result, but it's sure a nice environment to explore a new
language. Also, this program includes a 'long long' type displayed with
_printf.

Thanks to Andrew Crabtree for a suggestion I used in revising this
program: using a variable _stacksave to restore the value of %esp at the
end rather than reseting it after every printf. I'd be curious to learn,
by the way, if there's any guideline in more ambitious programs on how
large one should allow the stack to grow, or how often one should restore
%esp. 

Most appreciatively,

Margo


/*
 *	This standalone GAS file uses a long long type to calculate
 *	and store the distance of a light year measured in meters.
 *	Note the C-style output with _printf from within an assembler
 *	program; DJGPP makes possible this style, also used by some
 *	Linux programmers.
 *
 *	This code actually compiles successfully for me with
 *	DJGPP 2.01 (gcc 2.7.2.1, bnu 2.8.1):
 *		 
 *	gcc -o lightyr.exe lightyr.s 
 *
 *	This file is released under the GNU General Public 
 *	License (GPL), but is _not_ GNU software.
 *
 *	Margo Schulter
 *	mschulter AT value DOT net
 *	September 24, 1997		
*/
	
.file	"lightyr.s"

.data
	.global _result		# long long int for result
		.align 3
	_result:
		.int 0
		.int 0

	.global _light_second	# distance in meters
		.align 2
	_light_second:
		.int 299792458

	.global _minute		# 60 seconds in one minute
		.align 2
	_minute:
		.int 60

	.global _hour		# 60 minutes in one hour
		.align 2
	_hour:
		.int 60

	.global _day		# 24 hours in one day
		.align 2
	_day:
		.int 24

	.global _year		# 365 whole days in one year
		.align 2
	_year:
		.int 365

	.global _leaptime	# extra 5 hours, 48 minutes, 46 seconds
		.align 2
	_leaptime:	
		.int 20926

	.global _seconds_in_year	# global for seconds in year 
		.align 2
	_seconds_in_year:	
		.int 0

	.global _stacksave	# initial value of %esp, to restore
	_stacksave:		# before ret (thanks to Andy Crabtree)
		.int 0

/*
 *	Now for our strings to display, most in PostScript-like style
 *  	with \nnn as an "anti-spoiler" device
*/
	
string0:
	.ascii "\n\nThe velocity of light is %i meters per second.\n\0"
string1:
	.ascii "There are about %i seconds in a year.\n\0"
string2:
	.ascii "Therefore a light year is approximately %Ld meters.\n\0"
string3:
	.ascii "\n\n\52\52\52\52\52\52\52\52\52\52\52\52\52\0"
string4:	
	.ascii "\040\42\066\064\055\142\151\164\0"
string5:
	.ascii "\040\151\156\164\145\147\145\162\163\040\147\157\040\0"
string6:	
	.ascii "\141\040\140\154\157\156\147\040\154\157\156\147\047\0"
string7:	
	.ascii "\040\167\141\171\42\040\52\52\52\52\52\52\52\52\52\0"
string8:	
	.ascii "\52\52\52\0"
string9:
	.ascii "\n\52\52\52\52\52\52\52\52\52\040\107\145\0"
stringa:	
	.ascii "\164\040\164\150\141\164\040\145\170\164\162\141\040\160\0"
stringb:	
	.ascii "\145\164\141\155\145\164\145\162\040\157\146\040\155\151\0"
stringc:	
	.ascii "\154\145\141\147\145\040\167\151\164\150\040\107\101\0"
stringd:	
	.ascii "\123\041\040\52\52\52\52\52\52\52\52\52\n\n\0"

.text
.global _main
_main:	
	movl _light_second, %eax	# move variable into %eax 
	movl _minute, %ebx	# start calculating seconds in year
	imull _hour, %ebx	# %ebx = 60*60
	imull _day, %ebx	# %ebx = 60*60*24
	imull _year, %ebx	# %ebx = 60*60*24*365
	addl _leaptime, %ebx	# %ebx = (60*60*24*365) + 20926
	movl %ebx, _seconds_in_year   # store %ebx into variable 
	imull %ebx		# GAS syntax for result in %edx:%eax 

	movl %edx, _result+4	# move %edx part into upper 4 bytes
				# of our `long long' variable
	movl %eax, _result	# and %eax into lower 4 bytes 

/*
 *	Now that we've done our calculation, we get to have fun
 *	showing strings, sort of like in PostScript: put string
 *	on stack, and call _printf. This cumulatively decrements
 *	%esp, but we can restore _stacksave_ before exiting _main.
 *	Really neat for a 2GL <grin>.
*/	
	movl %esp, _stacksave	# store current value of %esp
				# in _stacksave to restore at end
				# of our _main
	pushl $string3
	call _printf
	pushl $string4
	call _printf
	pushl $string5
	call _printf
	pushl $string6
	call _printf
	pushl $string7
	call _printf
	pushl $string8
	call _printf

/*
 *	Now we move from the "desktop publishing" stuff to reporting
 *	our results: arguments for _printf go on stack, rightmost
 *	argument first, e.g. variable, then string.
*/	
	pushl _light_second
	pushl $string0
	call _printf
	pushl _seconds_in_year
	pushl $string1
	call _printf
	pushl _result+4		# first push upper 4 bytes
	pushl _result		# then lower 4 bytes
	pushl $string2		# (could this order be because
	call _printf		# i386 is little-endian?)

/*
 *	With our results reported, it's back to some more desktop
 *	publishing fun:	don't worry, PostScript and TeX still have
 *	their uses.
*/
	
	pushl $string9
	call _printf
	pushl $stringa
	call _printf
	pushl $stringb
	call _printf
	pushl $stringc
	call _printf
	pushl $stringd
	call _printf

	movl _stacksave, %esp	# restore stack pointer
	ret			# leave program









- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019