; Listing2-3.asm ; ; A program that demonstrates caling the math_acsc ; function. option casemap:none ; Include the aoalib (ANSI strings) and aoamath ; libraries: include aoalib.inc include math.inc includelib aoalib.lib includelib aoamath.lib .const ; Program title: align word ttlStr byte "Listing 2-3", 0 signBit qword 8000000000000000h .data align 16 aVal real8 -4.0 one real8 1.0 zero real8 0.0 aResult real8 0.0 point5 real8 0.5 .code ; External definitions for C/C++ atan function externdef atan:proc ; Here is the main assembly language function. public asmMain asmMain proc push rbx sub rsp, 64 ;Shadow storage + alignment ; Repeat for aVal = -4.0 to +4.0 by 0.5: mov rbx, 21 pgmLoop: ; Compute the assembly language result: math(acsc) aVal fstp aResult mov rdx, aVal mov r8, aResult call print byte "ASM.acsc(%4.1f)=%6.3f ", 0 ; There is no ACSC function in C/C++, must compute ; it as acsc(x) = Atan(Sign(x) / Sqrt(x * x - 1)) movsd xmm0, one movsd xmm2, aVal ;x movsd xmm1, xmm2 mulsd xmm2, xmm2 ;Compute x*x subsd xmm2, xmm0 ;Compute x*x-1 ; Compute xmm0=signum(x) by simply copying ; x's sign bit to '1': movsd xmm3, signBit ;xmm0=signum(x) pand xmm3, xmm1 por xmm0, xmm3 ; See if x*x-1 is less than or equal to zero ; before we try to compute its square root: comisd xmm2, zero ;Error if <= 0 jbe badSqrt ; Compute sqrt(x*x-1): sqrtsd xmm1, xmm2 ; Compute sign(x) / sqrt(x*x-1): divsd xmm0, xmm1 ; Compute Atan(Sign(x) / Sqrt(x * x - 1)): call atan ; Print the C result: movsd aResult, xmm0 mov rdx, aVal mov r8, aResult call print byte "C.acsc(%4.1f)=%6.3f", nl, 0 jmp nextIteration ; Drop down here if we tried to take the square root ; of a negative number or divide by zero: badSqrt: mov rdx, aVal call print byte "C.acsc(%4.1f)= -nan", nl, 0 nextIteration: fld point5 fld aVal faddp fstp aVal dec rbx jnz pgmLoop allDone: add rsp, 64 pop rbx ret ;Returns to caller asmMain endp end