2016-06-09 1 views
1

64bit 어셈블리 코딩을 처음 사용합니다.어셈블러에서 64 비트 즉시 값을 이동할 수 없습니다.

C-을 programm가 :

#include <stdio.h> 

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

어셈블리 : 나는 즉시없이 할 때

section .data 
    section .text 
    global bla 

    bla: 
    mov rax,10 
    movq xmm0,rax 
    ret 

그 결과는 alwals 대신 10.0 0.0 그러나 작동했다 그래서 나는 몇 가지 간단한 용 프로그램을 시도 괜찮음

#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 

Immed를로드하는 데 다른 지침이 필요합니까? 64 비트 레지스터에 보관 하시겠습니까?

+0

아래의 예는 작동하는 것처럼 보이지만 깨졌습니다. 첫 번째 어셈블러 코드의 코드는 정수 값 10을 rax로 이동 한 다음 rax의 정수 값을 xmm0으로 이동하려고 시도합니다. 문제는 movq가 범용 레지스터의 정수를 double로 변환하지 않고 xmm0에 저장한다는 것입니다. 레지스터의 정수 값을 변환하여 xmm0에 저장하려면 [CVTSI2SD] (http://www.felixcloutier.com/x86/CVTSI2SD.html)와 같은 명령어를 사용해야합니다. 이것은'bla :; mov eax, 10; cvtsi2sd xmm0, rax; ret' –

+0

이 예에서는 정수 값 10을 EAX로 이동합니다 (자동으로 0이 RAX로 확장 됨). 그러나 'mov rax, 10'도 수행 할 수 있습니다. 'cvtsi2sd xmm0, rax'는 RAX의 스칼라 정수를 스칼라 double (단일 부동 소수점 double)으로 변환하여 xmm0에 저장합니다. –

+0

다른 대안이 있습니다. NASM이 어셈블리 시간에 10.0을 64 비트 부동 소수점 상수 (10.0)로 변환하고이를 64 비트 범용 레지스터에 저장할 수 있습니다. 이것은 XMM 레지스터로 직접 이동할 수 있습니다 :'bla :; mov rax, __ float64 __ (10.0); movq xmm0, rax; ret' –

답변

1

문제 여기 영업 이익은 다음 코드를 사용하여 부동 소수점 레지스터에 10를 이동하려고했던 것이 었습니다 : xmm0movq 때문에,

mov rax,10 
movq xmm0,rax 

작동하지 않을 수 있습니다한다고 가정의 비트 패턴 소스는 이고 이미 부동 소수점 형식의입니다. 물론 그것은 아닙니다 : 정수입니다. 다음 예상되는 출력을 생산하고

mov rax,__float64__(10.0) 
movq xmm0,rax 

을 다음과 같이

@Michael 페치의 제안은 (NASM) 어셈블러의 부동 소수점 변환기를 사용하는 것이 었습니다.

관련 문제