1

こんにちは、アセンブリ ソースでいくつかの定数を宣言する必要があります。プログラムの特定の部分で、ループを制限するために、これらの定数の 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 の完全な 2 乗値しか取得できず、それは私が必要としているものではありません...

ご協力いただきありがとうございます!:)

4

1 に答える 1

2

このウィキペディアの記事で説明されている多くの平方根アルゴリズムの 1 つを、マクロを使用して実装できます。

これが私が思いついたものです:

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 に答える