汇编乘以指数nasm x64

时间:2013-11-05 22:07:05

标签: assembly x86-64 nasm exponent multiplying

我正在尝试计算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                                         

它只是挂起并输出任何东西。

1 个答案:

答案 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

顺便说一下,即使你的代码不是最优的,但在我添加了缺失的部分后,它似乎对我有用。