1

大家好,我需要在程序集源中声明一些常量。在程序的某个部分,我需要这些常量之一的(整数)平方根来限制循环。我的问题是:这甚至可能吗?

到目前为止,我尝试了类似的方法:

nMax EQU 200
nLimit EQU sqrt(nMax) ; of course won't assemble... 
                      ; just like nMax^0.5

当然我可以在运行时计算它,但这对我来说是无稽之谈......当然我可以做一个解决方法,比如:

nLimit EQU 14
nMax EQU nLimit*nLimit

但通过这种方式,我只能得到 nMax 的完美平方值,而这并不是我所需要的......

谢谢你的帮助!:)

4

1 回答 1

2

您可以使用宏来实现此 Wikipedia 文章中描述的许多平方根算法之一。

这是我想出的:

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

清单文件:

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
...
于 2013-03-21T00:25:47.480 回答