2014-10-20 11 views
4

우리의 학습 과제는 GNU 어셈블리에서 delta = b2 - 4ac 함수를 생성하고 C에서 액세스하도록 요청합니다. 이것은 컴파일러에 관한 과정이므로 어셈블리가 아니기 때문에 교수 정수 기능을 보여 주기만하고 정수 기능을 기대합니다.어셈블리 함수의 부동 소수점 복귀 액세스

그러나 저는 개인적인 학습이 의무를 넘어서고 정수가 아닌 부동 소수점을 반환하는 유용한 함수를 만들고 싶습니다.

# include <stdio.h> 

extern float delta(); 
float a, b, c; 

int main() { 
    a = 3; 
    b = 5; 
    c = 4; 
    printf("δ = %f\n", delta()); 
    return 0; 
} 

이 GNU 가스 :

.globl a 
.globl b 
.globl c 
.globl delta 
.f4: .float 4.0  # constante 4 

.text 
delta: 
    fld b   # b sur la pile 
    fmul b   # b2 sur la pile 
    fld .f4   # 4 sur la pile 
    fmul a   # 4a sur la pile 
    fmul c   # 4ac sur la pile 
    fsubp   # b2 - 4ac sur la pile 
ret 

내가이 C를 내놓았다 (하지 말자 전역 마음, 다음 연습의 목적은 적절한 매개 변수 기능을하는 것입니다)

Google에서 나는 부동 소수점 스택 맨 위에 부동 소수점 결과를 남겨 두어야한다고 생각하게되었지만 작동하지 않으며 C 호출자에 인쇄 된 결과는 항상 0.0000000입니다.

나는 아주 작은 것을 놓치지 만, 인터넷 검색 량이 없다면 누가 올바른 방향으로 나를 가리킬 수 있습니까? 감사합니다.

답변

4

나를 위해 작동합니다. 호출 규칙이 다르기 때문에 실수로 64 비트 모드를 사용하지 않도록하십시오. 즉, gcc -g -m32 foo.c bar.s을 사용하여 컴파일하십시오.

그렇다면 수정해야 할 잠재적 인 문제가 있음을 알았습니다.

  • 전역 변수가 C 코드로 정의되었으므로 어셈블리에 .globl을 사용하지 않아야합니다. 어떤 것이 든 .extern을 사용해야하지만 GAS는이를 요구하지 않습니다.
  • 기본 피연산자 크기에 의존해서는 안됩니다. 메모리 피연산자가있는 경우 부동 소수점에 접미사는 s이고 접미사는 l 접미사를 명시 적으로 사용해야합니다. 예를 들어, flds b이 플로트로로드되었는지 확인하십시오.
  • 스택 맨 꼭대기가 4ac이므로 을 사용해야하므로 fsubp을 사용하여 계산 한 값은 4ac-b^2입니다.
+0

감사합니다. m32 옵션은 내가 놓친 것입니다. 지금은 덜 유용한 방법으로 나머지 유용한 설명을 읽을 것입니다. 고맙습니다. – pouzzler

+0

어셈블 할 때'as'를 사용하면 해당 플래그는'as32 -o delta.o delta.s' 명령과 같이'--32'입니다. – Edward