Task

Create a program that calculates the hour, sun hour angle, dial hour line angle from 6am to 6pm for an operator entered location.



For example, the user is prompted for a location and inputs the latitude and longitude 4°57′S 150°30′W (4.95°S 150.5°W of Jules Verne's Lincoln Island, aka Ernest Legouve Reef), with a legal meridian of 150°W.

(Note: the "meridian" is approximately the same concept as the "longitude" - the distinction is that the meridian is used to determine when it is "noon" for official purposes. This will typically be slightly different from when the sun appears at its highest location, because of the structure of time zones. For most, but not all, time zones (hour wide zones with hour zero centred on Greenwich), the legal meridian will be an even multiple of 15 degrees.)

Wikipedia: A sundial is a device that measures time by the position of the Sun. In common designs such as the horizontal sundial, the sun casts a shadow from its style (also called its Gnomon, a thin rod or a sharp, straight edge) onto a flat surface marked with lines indicating the hours of the day (also called the dial face or dial plate). As the sun moves across the sky, the shadow-edge progressively aligns with different hour-lines on the plate. Such designs rely on the style being aligned with the axis of the Earth's rotation. Hence, if such a sundial is to tell the correct time, the style must point towards true north (not the north or south magnetic pole) and the style's angle with horizontal must equal the sundial's geographical latitude.




	global main
	extern printf, scanf
 
	section .text
 
getvalue:
	push	edx
	push	eax
	call	printf
	add	esp, 4
	push	in_ft
	call	scanf
	add	esp, 8
	ret
 
st0dr:
	fld	qword [drfact]
	fmul
	ret
 
 
main:	
	lea	eax, [lat_t]
	lea	edx, [lat]
	call    getvalue
	lea	eax, [lng_t]
	lea	edx, [lng]
	call	getvalue
	lea	eax, [ref_t]
	lea	edx, [ref]
	call	getvalue
 
	push	newline
	call	printf
	add	esp, 4
 
	fld	qword [lat]
	call	st0dr
	fsin
	fst	qword [slat]
 
	sub	esp, 8
	fstp	qword [esp]
	push	sin_ft
	call	printf
	add	esp, 12
 
	fld	qword [lng]
	fld	qword [ref]
	fsubr	st0, st1
	sub	esp, 8
	fstp	qword [esp]
	push	diff_ft
	call	printf
	add 	esp, 12
 
	push	tab_t
	call	printf
	add	esp, 4
 
	mov	ecx, -6
.loop:	
	cmp	ecx, 6
	jg	.endloop
 
	push	ecx
	fild	dword [esp]
	fld	qword [xv]
	fmulp
	fld	qword [lng]
	fsubp
	fld	qword [ref]
	faddp
	pop	ecx
 
	sub	esp, 20
	mov	dword [esp], ecx
	fst	qword [esp+4]
 
	call	st0dr
 
	fptan
	fxch
	fld	qword [slat]
	fmulp
	fxch
	fpatan
 
	fld	qword [rdinv]
	fmul
 
	fstp	qword [esp+12]
 
	push	o_ft
	call	printf
	mov	ecx, [esp+4]
	add 	esp, 24
 
	inc	ecx
	jmp	.loop
.endloop:
 
	xor	eax, eax
	ret
 
 
	section .data
 
lat:	dq	0.0
lng:	dq	0.0
ref:	dq	0.0
xv:	dq	15.0
slat:	dq	0.0
drfact:	dq	0.01745329251994329576
rdinv:	dq	57.29577951308232090712
 
 
	section .rodata
 
lat_t:	db "Enter latitude: ", 0
lng_t:	db "Enter longitude: ", 0
ref_t:	db "Enter legal meridian: ", 0
 
in_ft:	db "%lf", 0	
newline:	
	db 10, 0
 
sin_ft:	
	db "sine of latitude: %.3f", 10, 0
diff_ft:	
	db "diff longitude: %.3f", 10, 10, 0
 
tab_t:	
	db "Hour, sun hour angle, dial hour line angle from 6am to 6pm", 10, 0
 
o_ft:	
	db "HR= %3d;  ",9,"  HRA=%7.3f;  ",9,"  HLA= %7.3f", 10, 0