2016-06-09 2 views
1

Ich bin neu in 64-Bit-Assembly-Codierung. Also habe ich versucht, einige einfache Programme:Kann 64-Bit-Sofortwerte in Assembler nicht verschieben

c-Programm:

#include <stdio.h> 

extern double bla(); 
double x=0; 
int main() { 
    x=bla(); 
    printf(" %f",x); 
    return 0; 
} 

Montage:

section .data 
    section .text 
    global bla 

    bla: 
    mov rax,10 
    movq xmm0,rax 
    ret 

Das Ergebnis wurde alwals 0,0 statt 10,0 Aber wenn ich es machen, ohne eine unmittelbare es funktioniert fein

#include <stdio.h> 


extern double bla(double y); 
double x=0; 
double a=10; 
int main() { 
    x=bla(a); 
    printf("add returned %f",x); 
    return 0; 
} 


section .data 
section .text 
global bla 


bla: 
    movq rax,xmm0 
    movq xmm0,rbx ;xmm0=0 now 
    movq xmm0,rax ;xmm0=10 now 
ret 

Benötige ich eine andere Anweisung, um ein Immed zu laden iate in einem 64-Bit-Register?

+0

Das untere Beispiel scheint nur zu funktionieren, ist aber defekt. Der Code im ersten Assembler-Code verschiebt den Integer-Wert 10 in rax und versucht dann, den Integer-Wert in rax nach xmm0 zu verschieben. Das Problem ist, dass movq keine Integer in einem Allzweckregister in ein Double konvertiert und es in xmm0 speichert. Sie müssen eine Anweisung wie [CVTSI2SD] (http://www.felixcloutier.com/x86/CVTSI2SD.html) verwenden, um einen ganzzahligen Wert in einem Register zu konvertieren und in xmm0 zu speichern. Dies sollte funktionieren 'bla:; mov eax, 10; cvtsi2sd xmm0, rax; ret' –

+0

Das Beispiel verschiebt den ganzzahligen Wert 10 in EAX (automatisch wird NULL in RAX erweitert), aber Sie können 'mov rax, 10' auch tun. 'cvtsi2sd xmm0, rax' konvertiert die skalare Ganzzahl in RAX in ein skalares Doppel (ein einzelnes Gleitkommadoppel) und speichert es in xmm0. –

+0

Es gibt eine andere Alternative. Sie können NASM veranlassen, 10.0 bei der Montage in eine 64-Bit-Gleitkommakonstante (10.0) zu konvertieren und in einem 64-Bit-Allzweckregister zu speichern. Das kann direkt in ein XMM-Register wie folgt verschoben werden: 'bla:; mov rax, __ float64 __ (10,0); movq xmm0, rax; ret' –

Antwort

1

Das Problem dabei war, dass die OP versucht 10 in ein Floating-Point-Register mit dem folgenden Code zu verschieben:

mov rax,10 
movq xmm0,rax 

Das nimmt seit movq in xmm0 nicht arbeiten kann, dass die Bit-Muster der Quelle ist bereits im Gleitkommaformat - und natürlich ist es nicht: es ist eine ganze Zahl.

@ Michael Petch Vorschlag war die (NASM) Montage-Gleitkomma-Wandler zu verwenden, wie folgt:

mov rax,__float64__(10.0) 
movq xmm0,rax 

daß dann die erwartete Ausgabe erzeugt.