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! :)

有帮助吗?

解决方案

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
...
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top