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 表示正数),然后是 11 位指数偏置 1023,最后是 52 位尾数,隐含前导 1。数字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 回答