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 -