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?
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' –
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. –
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' –