我正在尝试计算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
它只是挂起并输出任何东西。
答案 0 :(得分: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
顺便说一下,即使你的代码不是最优的,但在我添加了缺失的部分后,它似乎对我有用。