컴퓨터 과학 수업에서 어셈블리를 배우기 시작하고 지정된 반올림 모드를 사용하여 부동 소수점 값을 반올림하도록 과제를 할당했습니다. . 나는 이것을 fstcw
, fldcw
및 frndint
을 사용하여 구현하려고 시도했습니다. 반올림 제어 비트를 수정하고 숫자를 반올림 한 다음 이전 제어 비트 (할당 요구 사항)를 복원합니다.인라인 어셈블리 (GCC, IA-32)에서 배정도 숫자로 작업하기
현재 뛰어난 문제) 명령 fld %1
내가 2.6207의 값을 가진 함수 수 -1.9427를 (호출하는 경우 (예를 들어, st(0)
부동 소수점 레지스터에 잘못된 값을로드하는 것 때문이다 .. e-29가 레지스터에로드 됨). 이는 gcc
의 인라인 asm()
또는 다른 것의 오용으로 인한 것일 수 있지만 그 이유는 확실하지 않습니다.
여기에 내가 가진 무엇 :
double roundD (double n, RoundingMode roundingMode)
{
// control word storage (2 bytes for previous, 2 for current)
char *cw = malloc(4*sizeof(char));
char *cw2 = cw + 2;
asm("fstcw %3;" // store control word in cw
"mov %3,%4;" // copy control word into cw2
"and $0xF3FF,%4;" // zero out rounding control bits
"or %2,%4;" // put new mode into rounding control bits
"fldcw %5;" // load the modified control word
"fld %1;" // load n into st(0)
"frndint;" // round n
"fstp %0;" // load st(0) back into n
"fldcw %3;" // load the old control word from cw
: "=m" (n)
: "m" (n), "m" (roundingMode),
"m" (cw), "r" (cw2), "m" (cw2) // mov requires one argument in a register
);
free(cw);
return n;
}
나는 특히 fld %1
라인과 asm
입력/출력에 관한, 그 코드 뭐가 잘못에 대한 포인터를 감사하겠습니다. (물론 다른 문제를 발견 할 수 있다면 그들에 대해서도 알려 주시기 바랍니다.) 나는 누군가가 나를 위해 숙제를하고 싶지 않다. 올바른 방향으로 나를 가리킨다. 감사!
와우, 그건 아주 불량합니다. 내가 도울 수 있으면 좋겠지 만 나는 못 하겠어! :) –
이 함수의 어셈블리 출력을 표시 할 수 있습니까? 그리고 너무 많은 문제가 아니라면 코드 바이트. –
@ 존 : 조립 될 코드는 놀랄 일이 아닙니다. 그것은 거대한 불투명 (gcc에) asm 블록에 모두있다. :-P 반면, 많은 작은 asm 문장 (내 게시물과 같은)으로 분할하는 것은 gcc가 다른 일을 할 수있는 더 위도를 줄 것입니다. –