Reputation: 352
Hy all, I need to declare some constants in an assembly source. In a certain part of the program I need the (integer) square root of one of those constants to limit a loop. My question is: is it even possible?
So far I tried something like:
nMax EQU 200
nLimit EQU sqrt(nMax) ; of course won't assemble...
; just like nMax^0.5
Of course I could compute it run-time, but it's a nonsense to me... And of course I could do a work-around like:
nLimit EQU 14
nMax EQU nLimit*nLimit
But in this way I can get only perfect squared value of nMax, and that is just not what I need...
Thanks for your help! :)
Upvotes: 1
Views: 1675
Reputation: 62068
You could implement one of the many square root algorithms described in this Wikipedia article using macros.
Here's what I've come up with:
NEWTON MACRO S, A
EXITM <(A + ((S) / (A))) / 2>
ENDM
SQRT MACRO N
LOCAL V
IF (N LT 0) OR (N GT 4294967295)
.ERR ; negative or too large argument
EXITM <0>
ENDIF
IF (N EQ 0) OR (N EQ 1)
EXITM <N> ; 0 or 1
ENDIF
; calculate approximations of the square root
; using Newton's method,
; initial approximation is N / 2
V = NEWTON(N, N / 2)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
V = NEWTON(N, V)
IF (V * V GT N) OR ((V * V) EQ 0)
EXITM <V - 1> ; return 1 less
; if the approximation is too big
; or
; if its square overflows to 0
ENDIF
EXITM <V>
ENDM
.386P
CODE SEGMENT PUBLIC USE32
ASSUME CS:CODE
ORG 0
start:
;mov eax, SQRT(-1)
mov eax, SQRT(0)
mov eax, SQRT(1)
mov eax, SQRT(2)
mov eax, SQRT(15)
mov eax, SQRT(16)
mov eax, SQRT(16+9)
mov eax, SQRT(256)
mov eax, SQRT(65535)
mov eax, SQRT(65536)
mov eax, SQRT(16769025)
mov eax, SQRT(1073676289)
mov eax, SQRT(2147483647)
mov eax, SQRT(2147483648)
mov eax, SQRT(4294705155)
mov eax, SQRT(4294705156)
mov eax, SQRT(4294705157)
mov eax, SQRT(4294967295)
;mov eax, SQRT(4294967296)
ret
CODE ENDS
END start
Listing file:
Microsoft (R) Macro Assembler Version 6.14.8444 03/21/13 01:51:53
sqrt.asm Page 1 - 1
...
00000000 CODE SEGMENT PUBLIC USE32
ASSUME CS:CODE
ORG 0
00000000 start:
;mov eax, SQRT(-1)
00000000 B8 00000000 mov eax, SQRT(0)
00000005 B8 00000001 mov eax, SQRT(1)
0000000A B8 00000001 mov eax, SQRT(2)
0000000F B8 00000003 mov eax, SQRT(15)
00000014 B8 00000004 mov eax, SQRT(16)
00000019 B8 00000005 mov eax, SQRT(16+9)
0000001E B8 00000010 mov eax, SQRT(256)
00000023 B8 000000FF mov eax, SQRT(65535)
00000028 B8 00000100 mov eax, SQRT(65536)
0000002D B8 00000FFF mov eax, SQRT(16769025)
00000032 B8 00007FFF mov eax, SQRT(1073676289)
00000037 B8 0000B504 mov eax, SQRT(2147483647)
0000003C B8 0000B504 mov eax, SQRT(2147483648)
00000041 B8 0000FFFD mov eax, SQRT(4294705155)
00000046 B8 0000FFFE mov eax, SQRT(4294705156)
0000004B B8 0000FFFE mov eax, SQRT(4294705157)
00000050 B8 0000FFFF mov eax, SQRT(4294967295)
;mov eax, SQRT(4294967296)
00000055 C3 ret
0056 CODE ENDS
END start
...
Upvotes: 2