1

2^(-n) を計算しようとしています。私のアプローチは、ループを使用して 2^n を計算し、1 をその数値で除算することです。私はこれをできるだけ読みやすくしようとしましたが、私はばかげている可能性があり、はるかに簡単な方法があります...

(後でベクトル処理のためにレジスタの高低の両方で計算を行っています)

formatfloatinput db "%lf", 0


two dq 2.0             ;a variable to be used later                             
one dq 1.0             ;a variable to be used later                                                

mov     r15, 1         ;counter for the loop

;scanf has been called, asking user to input "n"

pop     r12            ;r12 will contain "n"

;===== Copy some data to xmm registers=========================

push    r12            ;push r12 onto stack
push    r12            ;push r12 onto stack

movupd xmm5, [rsp]     ;move both values into "high" and "low" of xmm5

pop rax                ;reverse push
pop rax                ;reverse push



push qword [two]       ;push 2 onto stack
push qword [two]       ;push 2 onto stack

movupd xmm6, [rsp]     ;push 2 into "high" and "low" of xmm6 for the "2^n" calculation

pop rax                ;reverse push
pop rax                ;reverse push


push qword [one]       ;push 1 onto stack
push qword [one]       ;push 1 onto stack

movupd xmm7, [rsp]     "push 1 into "high" and "low" of xmm7 for division later"

pop rax                ;reverse push
pop rax                ;reverse push

;================================================================

movupd xmm4,xmm6       ;places 2's into xmm4. this is to multiply xmm6 with later in the loop

beginExponent:         ;begin loop for calculating exponent

mulpd xmm4,xmm6        ;multiply 2x2
inc r15                ;increment counter

cmp r12,r15            ;is the counter the same as the user specified "n"?


jne beginExponent      ;if not, go up and loop again



divpd xmm7,xmm4        ;divide 1 by (2^n)
movsd xmm0,xmm7        ;mov "just high or low, can't remember" of xmm7 into xmm0

mov qword rdi, formatfloatinput
mov qword rax, 1                                            
call      printf                                         

ハングして何も出力しません。

4

1 に答える 1

2

標準浮動小数点形式の詳細については、wikipediaを参照してください。倍精度には先頭の符号ビット (正の場合は 0) があり、次に 1023 でバイアスされた 11 ビットの指数、最後に暗黙の先行 1 を持つ 52 ビットの仮数があります。数値の2^-n符号は 0 で、仮数は 0 になります (仮数の値が 1 であるため)。ただし、先頭の 1 は省略されます)、指数は になります1023-n。このパターンは、否定、加算、およびシフトによって簡単に作成できます。

section .data
formatfloatinput db "%lf", 0

section .text
global main
extern printf
main:
    push rbp        ; maintain stack alignment
    mov r12, 3      ; fetch input into r12 here, use 3 as example
    neg r12         ; get -n
    add r12, 1023   ; add the double-precision exponent bias
    shl r12, 52     ; shift into place
    ; sign and mantissa are zero, we are done
    movq xmm0, r12
    mov rdi, formatfloatinput
    mov eax, 1
    call printf
    xor eax, eax
    pop rbp
    ret

ちなみに、あなたのコードは最適ではありませんが、不足している部分を追加した後、うまくいくように見えました.

于 2013-11-06T01:59:24.137 に答える