2012-06-03 2 views
4

일부 x86-64 어셈블리와 관련하여 고민 중입니다. 부동 소수점 숫자로 인해 두통이 생깁니다. 이 코드를 실행하면 예를 들어, :x86-64 어셈블리에서 부동 소수점 숫자를 사용하는 방법은 무엇입니까?

section .data 
    omega: dq 2.0 
    omega2: dq 3.0 

section .text 
global func 

func: push rbp 
     mov rgp, rsp 

     FINIT 

     FLD qword [omega] 
     FLD qword [omega2] 
     FADD st0, st0 

     mov rsp, rbp 
     pop rbp 
     ret 

이 기능은 그런 C 코드에서 호출됩니다 printf("%Lf \n", func()); 불행하게도 그 결과는 어떤 기괴한 숫자입니다 ... 나는 FIADD를 사용하여 두 개의 정수를 추가했는데, 그것은 일 벌금. 나는 이미 재료의 톤을 파고,하지만 어쩌면 여기에 누군가가 괜찮은 FPU 튜토리얼 날 지점, 또는 필수을 포장 그녀/그의 경험과 지혜 :

를 공유 할 수 있습니다

  • 언어 : 86 - 64 어셈블러
  • 어셈블러 :.. GCC의 V 4.5.2 (우분투 설치)
  • OS : NASM 2.09.04 V는 (C 용) 저장소에서
  • 컴파일러 설치 우분투 11.04 64 비트 오라클 VM
  • 에 호스트 OS : Wi ndows 7 SP1 64 비트
  • 프로세서 : 인텔의 i5 - 2430M 64 비트 (2 회 검사 : D)
  • 이 문제 : 이런 경우에 두 개의 번호 :(

를 추가 할 수 없습니다 FPU : 결국 내가 희망 FSINCOS과 다른 멋진 FPU 명령어를 사용하십시오. 그러나 심지어 단순한 추가가 실패로 간주됩니다 ...

미리 감사드립니다!

+2

복잡성을 파악하는 한 가지 방법은 간단한 C 코드를 컴파일하고 결과 기계 코드를 역 어셈블러로 살펴 보는 것입니다. –

+0

글쎄, SSE 명령어 세트를 사용하는 것 같습니다. 아마 내일이 접근법을 시도 할 것입니다. – Losiowaty

+4

x86_64에서 레거시 FPU를 사용하지 마십시오. 적어도 그렇게해서는 안됩니다. 스칼라 SSE 명령을 더 잘 사용하십시오. – hirschhornsalz

답변

2

좋아, 결국 내 문제는 FPU 레지스터가 스택으로 구성되어 있다는 사실과 관련이 있으며, 충분히주의를 기울이지 않아 쓰레기와 불필요한 부분이 생겼다. 지침의 "표준"버전에서 "팝"버전으로 전환하면 도움이되었습니다!

어쨌든 - 읽으 려하는 모든 사람 덕분에, 대단히 감사합니다! :)

누구든지 관심이 있다면 - 어셈블리에서 다른 (지구 중심 모델) 관점에서 한 행성의 동작을 계산해야하는 클래스 할당을 수행하고있었습니다. The final result translated to processing can be viewed here.

0

L printf % f 한정자는 해당 인수를 어셈블리 데이터 형식이 아닌 long double (80 비트 float)이되게합니다. L을 제거하면 기본값 인 double (64 비트 부동)이 계산됩니다.

또한,

FADD st1, st0 

함께 두 숫자를 추가해야합니다. 그렇지 않으면 두 번째 값이 두 배가됩니다.

+0

글쎄, 문제는 여전히 있습니다. – Losiowaty

+0

@Losiowaty :'C' 코드는'func()'에 대한 선언을 가지고 있습니까? – wallyk

+0

그렇지 않으면 컴파일하는 동안 링커 오류가 발생합니다. 그리고 추가 수식이 맞지만 여전히/sub/div/mul을 추가하려고해도 상관 없습니다. – Losiowaty